首页 > 解决方案 > 如何管理不总是填写的查询参数?

问题描述

我的模型如下所示:

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 一样。

没有更简单的方法可以做到这一点吗?谢谢你。

标签: javascriptnode.jsreactjsmongodbreact-router

解决方案


将您的逻辑放在服务器端是最佳实践。在这种情况下,实现您想要的并不难。

请记住,没有通用的“性感”方式来实施特定业务。但是没有理由对实现支持它的逻辑持谨慎态度。

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));
});

推荐阅读