我有2个MongoDB集合。关键字和PersonalInfo。我从客户端收到这样的数组:
[
{fieldName : 'Keyword',operator: '===',value: 'soccer'},
{fieldName : 'Keyword',operator: 'endsWith',value: 'cer'},
{fieldName : 'Name',operator: 'startsWith',value: 'mik'}
]
我正在使用NodeJ,需要动态构建MongoDB查询。 我已经尝试过了。
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"
}
}
]);
感谢您的时间,感谢您的帮助。
答案 0 :(得分:1)
您做得正确,我不确定您是如何获得“输出”的(假设您打印了它),但是它只是向您显示对象内部的内容,这是预期的另一个对象。
完整的代码如下所示:(仅出于可读性考虑将其清除了一点)
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
值{1}}至"Name"
。编辑:
使用它代替上面的语法:
"$$name"
您也没有将您的 let val = new RegExp(data[i].value, "i");
and_conds.push({[field_name]: val)`
更改为fieldName
,所以您也应该这样做。