Javascript 如何使用多个或多个查询动态构建MongoDB查询?

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"}},

我希望能够使用具有多个OR的节点动态构建Mongo查询。此查询的目的是使用多个搜索词在数据库中执行AND搜索

例如,假设有人想要搜索包含单词“dog”和“grane”的记录。该查询只会返回记录中某处包含“dog”和“grane”的记录(即搜索词可以出现在不同的列中)

我知道查询结果应该是这样的:

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;

    })};

})};