Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/452.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何管理不总是填写的查询参数?_Javascript_Node.js_Reactjs_Mongodb_React Router - Fatal编程技术网

Javascript 如何管理不总是填写的查询参数?

Javascript 如何管理不总是填写的查询参数?,javascript,node.js,reactjs,mongodb,react-router,Javascript,Node.js,Reactjs,Mongodb,React Router,我的模型如下所示: 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: {typ

我的模型如下所示:

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));
});
然而,我们决定,当用户在wichever播放器字段中输入一个值时,无论是player1还是player2,db都会返回Replay,这会更好。考虑到所有可选值,如您所见,有许多不同的查询可以从用户对填充/不填充每个值的所有不同选项中得出

我的第一个想法是检查哪些值填充了ifs,并根据它们进行不同的查询,但这意味着超过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));
});

@TomSlabbaert为我指明了正确的方向,我应该将mongo db的查询处理为数组中的数组

最终,我的问题的解决方案是:

const router = require('express').Router();
let Replay = require('../models/Replay.model');

router.route('/').get((req,res) => {
   //console.log(req.query);
   let andConds = [];


   if (req.query.game) {
       andConds.push({game: req.query.game})
   }

   if (req.query.player1 || req.query.player2 || req.query.character1 || req.query.character2) {
       let orCondition = [];
       let stAndOrCondition =[];
       let ndAndOrCondition = [];
       if (req.query.player1) {
           stAndOrCondition.push({player1: req.query.player1})
           ndAndOrCondition.push({player2: req.query.player1})
       }

       if (req.query.player2) {
           stAndOrCondition.push({player2: req.query.player2})
           ndAndOrCondition.push({player1: req.query.player2})
       }

       if (req.query.character1) {
           stAndOrCondition.push({character1: req.query.character1})
           ndAndOrCondition.push({character2: req.query.character1})
       }
       if (req.query.character2) {
           stAndOrCondition.push({character2: req.query.character2})
           ndAndOrCondition.push({character1: req.query.character2})
       }
       orCondition.push({$and: stAndOrCondition})
       orCondition.push({$and: ndAndOrCondition})
       andConds.push({$or: orCondition})
       console.log(JSON.stringify(andConds))
   }



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

module.exports= router;



所以你想搜索player1或player2,不管用户输入哪一个?如果输入被切换怎么办?输入的
{player1:'A',player2:'B'}
是否与
{player1:'B',player2:'A'}
匹配?那么角色1和角色2呢?@TheeSritabtim和你对玩家说的一模一样,是的,角色必须“链接”到玩家,这使得事情更加复杂。因此,当您查找
{player1:'A',character1:'C1'}
时,数据库应该返回
{player1:'A',character1:'C1'}
{player2:'A',character2:'C1'}
的实例。这个答案帮助我了解了如何管理此类查询,但您的答案中仍然遗漏了一些内容。character1和character2字段的行为也应类似于player1和player2,其中如果character1已填充,db应返回该角色出现在character1或character2中的实例,问题是它应链接到播放器,因此如果填充了player1:person和character1:character字段,db应该返回person在player1中,character在character1中,person在player2中,character在character2中的所有实例。原始逻辑没有这样做,所以我只是照原样做了。显然,只要改变你所需要的一切,它就会如你所期望的那样工作。