Javascript 如何使用多个或多个查询动态构建MongoDB查询?
我希望能够使用具有多个OR的节点动态构建Mongo查询。此查询的目的是使用多个搜索词在数据库中执行AND搜索 例如,假设有人想要搜索包含单词“dog”和“grane”的记录。该查询只会返回记录中某处包含“dog”和“grane”的记录(即搜索词可以出现在不同的列中) 我知道查询结果应该是这样的:Javascript 如何使用多个或多个查询动态构建MongoDB查询?,javascript,node.js,mongodb,mongodb-query,Javascript,Node.js,Mongodb,Mongodb Query,我希望能够使用具有多个OR的节点动态构建Mongo查询。此查询的目的是使用多个搜索词在数据库中执行AND搜索 例如,假设有人想要搜索包含单词“dog”和“grane”的记录。该查询只会返回记录中某处包含“dog”和“grane”的记录(即搜索词可以出现在不同的列中) 我知道查询结果应该是这样的: query = { $and: [ {$or: [ {col1: {$regex: "first", $options: "i"}},
query = {
$and: [
{$or: [
{col1: {$regex: "first", $options: "i"}},
{col2: {$regex: "first", $options: "i"}}
]},
{$or: [
{col1: {$regex: "second", $options: "i"}},
{col2: {$regex: "second", $options: "i"}}
]}
]
}
但是,我的节点代码不会产生这种情况。
这是我最接近于弄明白这一点的一次:
var regexQueryWrapper = {};
regexQueryWrapper["$and"] = [];
var wrapper = {};
wrapper["$or"] = [];
var query = {};
searchTerms.forEach(function(term) {
searchFields.forEach(function(field) {
query[field] = {$regex: term, $options: 'i'};
wrapper["$or"].push(query);
});
regexQueryWrapper["$and"].push(wrapper);
});
最好的方法是什么?我缺少的是另一种方法吗?我想你把这件事复杂化了 通过考虑您主要操作两个嵌套数组(
和
和或
)的事实,逐步构建查询
使用一个推送数组的函数和另一个返回数组的函数,NodeJS代码将是:
query = {and: []};
function add_and(or_query) {
query["and"].push({or: or_query});
}
function build_or_query(term) {
return [
{col1 : {$regex: term, $options: "i"}},
{col2: {$regex: term, $options: "i"}}
]
}
重命名并在代码中适当使用这些函数来管理用户输入事件。如果愿意,还可以合并它们,以确保代码非常紧凑:
function add_and(term) {
query["and"].push({or: [
{col1 : {$regex: term, $options: "i"}},
{col2: {$regex: term, $options: "i"}}
]});
}
使用like(两个函数):
或类似(一个功能):
结果:
{
and: [
{ or: [ { col1: { '$regex': 'test1', '$options': 'i' } },
{ col2: { '$regex': 'test1', '$options': 'i' } } ] },
{ or: [ { col1: { '$regex': 'test2', '$options': 'i' } },
{ col2: { '$regex': 'test2', '$options': 'i' } } ] }
]
}
你很接近。您似乎正在重用对象。下面是一些经过调整的代码,用于构建您要查找的查询,并在每次forEach迭代中重新初始化临时对象:
var regexQueryWrapper = {};
regexQueryWrapper["$and"] = [];
searchTerms.forEach(function(term) {
var wrapper = {"$or": []};
searchFields.forEach(function(field) {
var query = {};
query[field] = {$regex: term, $options: 'i'};
wrapper["$or"].push(query);
});
regexQueryWrapper["$and"].push(wrapper);
});
以及使用map
的替代实现:
var query = {"$and": searchTerms.map(function(term) {
return {"$or": searchFields.map(function(field) {
var o = {};
o[field] = {"$regex": term, "$options": "i"};
return o;
})};
})};
你有没有考虑过用MongoDB来做这个?你的用例听起来很适合。@johnyhk我有,我很乐意使用它。但是,它与应用程序所需的搜索不同。当我在上尝试您的解决方案时,我被告知它是无效的javascript。这很奇怪,因为我觉得一切都很好…PS:我在你的网站上试过了,效果很好,当你在网站上测试最短的解决方案时,删除了“build_或_query”(“build_或_query”)。我最初更喜欢使用两个功能,以提供更大的灵活性,所以我在答案中保留了较长的解决方案。
var regexQueryWrapper = {};
regexQueryWrapper["$and"] = [];
searchTerms.forEach(function(term) {
var wrapper = {"$or": []};
searchFields.forEach(function(field) {
var query = {};
query[field] = {$regex: term, $options: 'i'};
wrapper["$or"].push(query);
});
regexQueryWrapper["$and"].push(wrapper);
});
var query = {"$and": searchTerms.map(function(term) {
return {"$or": searchFields.map(function(field) {
var o = {};
o[field] = {"$regex": term, "$options": "i"};
return o;
})};
})};