javascript - 如何管理不总是填写的查询参数?
问题描述
我的模型如下所示:
const replaySchema = new Schema({
game: {type: String, required:true},
link: {type: String, required:true,unique: true},
player1: {type: String, required: true},
player2: {type: String, required: true},
character1: {type: String, required: true},
character2: {type: String, required: true}
},{
timestamps:true,
});
我的用户填写了一个表单,其值与模型相同,他可以将大部分参数留空,例如,他只能填写游戏和 player1 字段。
在提交表单时,会创建一个新的 const,它会在其中获取表单中填充输入的参数和值,然后将其发送到params
字段中的后端。
onSubmit(e){
e.preventDefault();
const replay = {};
this.state.game && (replay.game = this.state.game);
this.state.player1 && (replay.player1 = this.state.player1);
this.state.player2 && (replay.player2 = this.state.player2);
this.state.character1 && (replay.character1 = this.state.character1);
this.state.character2 && (replay.character2 = this.state.character2);
console.log(replay);
axios.get("http://localhost:5000/search/",
{params:replay}).then(response => {
this.setState({
replays: response.data
})
}).catch((error) => {
console.log(error);
})
}
后端最初会像这样处理它。
router.route('/').get((req,res) => {
console.log(req.query);
Replay.find(req.query).then(replays => res.json(replays)).catch(err => res.status(400).json('Error: ' + err));
});
但是,我们认为最好是当用户在任何玩家字段中输入值时,无论是 player1 还是 player2,db 都会返回重播。考虑到所有可选值,如您所见,可以从用户填充/不填充每个值的所有不同选项中得出许多不同的查询。
我的第一个想法是检查哪些值填充了 if 并根据它进行不同的查询,但这意味着超过 16 个不同的查询,这听起来不太干净。
然后我考虑按顺序构造一个查询字符串,但考虑到 $or 和 $in 的 mongodb 结构,尝试这样做几乎就像用很多 ifs 一样。
没有更简单的方法可以做到这一点吗?谢谢你。
解决方案
将您的逻辑放在服务器端是最佳实践。在这种情况下,实现您想要的并不难。
请记住,没有通用的“性感”方式来实施特定业务。但是没有理由对实现支持它的逻辑持谨慎态度。
router.route('/').get((req,res) => {
console.log(req.query);
let andConds = [];
if (req.query.character1) {
andConds.push({character1: req.query.character1})
}
if (req.query.character2) {
andConds.push({character2: req.query.character2})
}
if (req.query.game) {
andConds.push({game: req.query.game})
}
if (req.query.player1 || req.query.player2) {
let orCond = [];
if (req.query.player1) {
orCond.push({player1: req.query.player1})
orCond.push({player2: req.query.player1})
}
if (req.query.player2) {
orCond.push({player1: req.query.player2})
orCond.push({player2: req.query.player2})
}
andConds.push({$or: orCond})
}
//if no conditions exists match all as before.
Replay.find(andConds.length ? {$and: andConds} : {}).then(replays => res.json(replays)).catch(err => res.status(400).json('Error: ' + err));
});
推荐阅读
- reactjs - 如何使用 React redux 和 socket.io 将数据传递给客户端?
- php - 循环开始结束时间加上第二天的分钟
- docker - 如何在我的自托管 github 操作运行器上启用非 docker 操作来访问 docker 创建的文件?(无根码头工人)
- android - Android - 交换系统。SystemClock.uptimeMillis() 的 currentTimeMillis() - 含义是什么
- performance - Elasticsearch 术语聚合花费太多时间
- shopify - 将集合页面 Shopify 中变体产品的“添加到购物车”更改为“选择选项”
- java - 我们如何从 Set 获取我们在请求中传递的无效值
> - django - “NoneType”对象没有“用户名”属性?我应该怎么办?
- reactjs - 如何在不丢失全局状态的情况下在应用内导航?
- python - 大型 QAbstractTableModel 的 QTableView 动态行高