Динамический запрос MongoDB

#node.js #mongodb #express #mongoose

#node.js #mongodb #экспресс #мангуст

Вопрос:

Я пытаюсь создать объект запроса MongoDB на основе данных, полученных из формы поиска на стороне клиента. Моя цель — запросить базу данных с любыми критериями, предоставленными пользователем, при этом позволяя пользователю оставлять некоторые поля поиска пустыми, если они захотят.

Это моя текущая попытка объекта запроса:

 var q = {}; // declare the query object
  q['$and']=[]; // filter the search by any criteria given by the user
  if((req.body.learninglanguages).length > 0){ // if the criteria has a value or values
    q["$and"].push('{learningLanguages: {$in: '   req.body.learninglanguages.split(",")   '}}'); // add to the query object
  }
  if((req.body.spokenlanguages).length > 0){
    q["$and"].push('{spokenLanguages: {$in: '   req.body.spokenlanguages.split(",")   '}}');
  }
  if((req.body.country).length > 0){
    q["$and"].push('{country: {$in: '   req.body.country.split(",")   '}}');
  }
  if((req.body.commethod).length > 0){
    q["$and"].push('{comMethod: {$in: '   req.body.commethod.split(",")   '}}');
  }
  

Но результирующий объект:

 { '$and': 
   [ '{learningLanguages: {$in: Albanian,American Sign Language,Amharic,Arabic,Arabic (Egyptian)}}',
     '{spokenLanguages: {$in: Akan,Albanian,American Sign Language,Amharic}}',
     '{country: {$in: Åland Islands}}',
     '{comMethod: {$in: whatsapp,email,face to face,skype}}' ] }
  

Как я могу правильно построить запрос MongoDB $in из объектов req.body?

Комментарии:

1. Вы ознакомились с документацией? docs.mongodb.com/manual/reference/operator/query/in

2. У меня есть, но я не могу найти ничего полезного в динамическом построении объектов запроса.

3. Пожалуйста, обязательно проверьте мой ответ ниже и отметьте его правильно, если он соответствует вашим потребностям

4. Это превышает мои потребности! Спасибо за такой полный и исчерпывающий ответ.

5. Нет проблем! Рад, что смог помочь!

Ответ №1:

Проблема с вашим запросом заключается в том, что вы пытаетесь создать строку вместо непосредственного построения объекта, например, MongoDB и mongoose accept:

 var q = {}; // declare the query object
  q['$and']=[]; // filter the search by any criteria given by the user
  if((req.body.learninglanguages).length > 0){ // if the criteria has a value or values
    q["$and"].push({ learningLanguages: {$in: req.body.learninglanguages.split(",") }}); // add to the query object
  }
  if((req.body.spokenlanguages).length > 0){
    q["$and"].push({ spokenLanguages: {$in: req.body.spokenlanguages.split(",") }});
  }
  if((req.body.country).length > 0){
    q["$and"].push({ country: {$in: req.body.country.split(",") }});
  }
  if((req.body.commethod).length > 0){
    q["$and"].push({ comMethod: {$in: req.body.commethod.split(",") }});
  }
  

Вы можете видеть, что вместо ввода строки я вместо этого вставляю прямой объект, который соответствует спецификациям документации.

Смотрите документацию здесь для получения дополнительной информации:

  1. https://docs.mongodb.com/manual/reference/operator/query/and/
  2. https://docs.mongodb.com/manual/reference/operator/query/in/

И вот рабочий jsbin процесс, с которым вы можете поиграть:

  1. http://jsbin.com/cequbipiso/edit?js ,консоль

Комментарии:

1. Огромное спасибо. Застрял на этом некоторое время.

Ответ №2:

Я последовал предложению Дерека, которое является точным с точки зрения того, как динамически создавать условия запроса. Но, похоже, этот код не обрабатывает сценарий, в котором не указаны параметры поиска.

В частности, если все параметры req.body пусты, то у вас есть объект запроса с пустым $и массивом, как объявлено здесь:

 q['$and']=[];
  

Это приводит к MongoError: $and/$or/$nor must be a nonempty array ошибке.

Вот что я сделал, чтобы исправить эту проблему:

 var conditions = {}; //declare a conditions object
var and_clauses = []; //an array for the and conditions (and one for or conditions and so on)

if((!!req.body.email_id)){
    and_clauses.push({ 'email_id': {$regex: req.body.email_id }});
}   

if(and_clauses.length > 0){ 
    conditions['$and'] = and_clauses; // filter the search by any criteria given by the user
}

//Run the query
User.find(conditions,
    function(err, users) {
        if (err){
            console.log(err);
            res.status(500).send(err);
        }else{
            console.log(users);
            res.status(200).json(users);
        }
});
  

Дерек, прошу прощения, если я что-то не так понял, не хочу указывать на проблему неправильно.

Комментарии:

1. Привет, Викас, спасибо, что добавили дополнительный шаг к ответу Дерека. Это хорошо сработало для моего сценария.

2. В сочетании с логикой Дерека это решило мою проблему. Спасибо.