首页 > 解决方案 > 如何构建动态 MongoDB 查询

问题描述

我有 2 个集合 MongoDB。关键字和个人信息。我从客户端收到一个数组,如下所示:

[
 {fieldName : 'Keyword',operator: '===',value: 'soccer'},
 {fieldName : 'Keyword',operator: 'endsWith',value: 'cer'},
 {fieldName : 'Name',operator: 'startsWith',value: 'mik'}
]

我正在使用需要动态构建 MongoDB 查询的 NodeJs。我试过这样。

 let q = {};
  q["$and"] = [];

  let data = req.body;
  for (let i = 0; i < data.length; i++) {
    // I tried without consideration of "operator" first but couldn't succeed. 

    let val = new RegExp(data[i].value);
    if (data[i].fieldName === "Keyword") {
      q["$and"].push({ Keyword: { $regex: val, $options: "-i" } });
    } else if (data[i].fieldName === "Name") {
      q["$and"].push({ Name: { $regex: val, $options: "-i" } }); //Since this field is from another collection, so instead of Name i want to push it as "$$name" so i could be able to use it in aggregates. 


    } 
  }

我期待看到这样的输出。

{$and: 
[
 {Keyword: {$regex: 'search val', $options: "-i"}},
 {Name: {$regex: 'search val', $options: "-i"}},
]
}

但我得到的是:

{$and: 
 [
 {Keyword: [Object]},
 {Name: [Object]},
]
}

我如何构建上述查询并在聚合中实现它;

await Keyword.aggregate([
 {
  $lookup: {
    from: "PersonalInfo",
    let: { name: "$Name" },
    pipeline: [{ $match: { $expr: q } }],
    as: "searchRecords"
  }
}
 ])

这是我的完整代码。

let q = {};
  let results;
  let data = req.body;
  let and_conds = [];
  for (let i = 0; i < data.length; i++) {
    let val = new RegExp(data[i].value);
    let field_name = data[i].fieldName;
    and_conds.push({ [field_name]: { $regex: val, $options: "-i" } });
  }
  q["$and"] = and_conds;

let records = await KeyInfo.aggregate([
   {
      $lookup: {
        from: "PersonalInfo",
        let: { name: "$name" },
        pipeline: [{ $match: { $expr: q } }],
        as: "searchRecords"
      }
    }
   ]);

感谢您的宝贵时间并感谢您的帮助。

标签: node.jsmongodbmongoosemongodb-query

解决方案


你做得对,我不确定你是如何得到你的“输出”(假设你打印了它),但它只是向你展示了你的对象内部的内容,这是预期的另一个对象。

完整的代码如下所示:(为了便于阅读,稍微清除了一点)

  let q = {};

  let data = req.body;
  let and_conds = [];
  for (let i = 0; i < data.length; i++) {
    let val = new RegExp(data[i].value);
    let field_name = data[i].fieldName;
    and_conds.push({[field_name]: { $regex: val, $options: "-i" }})
  } 
  q["$and"] = and_conds;
  • 我不确定您的$$name评论是什么意思,因为您在匹配阶段查找后仅使用这些条件,但如果您所要做的就是将field_name值从更改"Name""$$name"

编辑:

使用它而不是上面的语法:

    let val = new RegExp(data[i].value, "i");
    and_conds.push({[field_name]: val)`

你也没有改变你fieldName"$$name"你也应该这样做。


推荐阅读