Mongo +检查现有的多个字段

时间:2016-09-07 07:20:08

标签: node.js mongodb

我正在使用nodejs工作mongo。

我有数组列表:

var checkFields = ["field1","field2","field3"];

我尝试获取具有数组列表字段且用户字段等于admin的记录数。

示例数据:

[
    {  
        "checkFields": { 
            "field1": "00124b3a5c31", 
            "user": "admin" 
        } 
    },
    {  
        "checkFields": { 
            "field2": "00124b3a5c31", 
            "user": "admin" 
        } 
    },
    { 
        "checkFields": { 
            "field1": "00124b3a5c31", 
            "user": "regular" 
        } 
    }
]

查询:

db.collection_name.find(
    {"checkFields.user" : "admin"} 
    { "checkFields.field1": { $exists: true} } 
)

预期结果:

结果是获取与数组list(checkFields)中的字段匹配的计数行。

3 个答案:

答案 0 :(得分:1)

为字段存在检查列表构建$or数组是正确的方法,但假设您使用的是当前node.js构建,则可以将查询创建简化为:

var checkFieldsLists = checkFields.map(field => ({
    ['checkFields.' + field]: {$exists: true}
}));
var query = {
    $or: checkFieldsLists,
    'checkFields.user': 'admin'
}

这会删除“user is admin”检查的多余$or,这样您还可以删除外部$and,以便生成的查询为:

{ '$or':
   [ { 'checkFields.field1': { '$exists': true } },
     { 'checkFields.field2': { '$exists': true } },
     { 'checkFields.field3': { '$exists': true } } ],
  'checkFields.user': 'admin' }

答案 1 :(得分:0)

以下是使用汇总查询的解决方案。

var Db = require('mongodb').Db, Server = require('mongodb').Server, assert = require('assert');

var db = new Db('localhost', new Server('localhost', 27017));

var checkFields = ["field1", "field2", "field3"];

var checkFieldsLists = [];
for (var i = 0; i < checkFields.length; i++) {
    var jsObj = {};
    jsObj['checkFields.' + checkFields[i]] = {};
    jsObj['checkFields.' + checkFields[i]].$exists = true;
    checkFieldsLists.push(jsObj);
}

var query = {
    "$and" : [{
        "$or" : checkFieldsLists
    }, {
        "$or" : [{
            "checkFields.user" : "admin"
        }]
    }]
}; 

var matchQuery = {
    "$match" : {
        "checkFields.user" : "admin",
        "$or" :  checkFieldsLists 

    }
};

var groupQuery = {
    $group : {
        _id : null,
        count : {
            $sum : 1
        }
    }
};

var aggregateCheckFields = function(db, callback) {
    console.log("Match query is ====>" + JSON.stringify(matchQuery));
    console.log("Group query is ====>" + JSON.stringify(matchQuery));
    db.collection('checkfields').aggregate([ matchQuery, groupQuery ]).toArray(
            function(err, result) {
                assert.equal(err, null);
                console.log("Result is ===>" + JSON.stringify(result));
                if (result.length > 0) {
                    console.log("Count is ===>" + result[0].count); 
                }               
                callback(result);
            });
};

db.open(function(err, db) {

    aggregateCheckFields(db, function() {
        db.close();
    });

});

<强>输出: -

Result is ===>[{"_id":null,"count":3}]
Count is ===>3

答案 2 :(得分:0)

我尝试了以下代码。它的工作但不知道它的良好解决方案和性能。请任何人有更好的答案意味着请发布。

var checkFields = ["field1", "field2", "field3"];

var checkFieldsLists = [];
for ( i = 0; i < checkFields.length; i++) {
    var jsObj = {};
    jsObj['checkFields.' + checkFields[i]] = {};
    jsObj['checkFields.' + checkFields[i]].$exists = true;
    checkFieldsLists.push(jsObj);
}

var query = {
    "$and" : [{
        "$or" : checkFieldsLists
    }, {
        "$or" : [{
            "checkFields.user" : "admin"
        }]
    }]
};

console.log(JSON.stringify(query));
//console log will return
/*
   {"$and":[{
        "$or" : [{
            "checkFields.field1" : {
                "$exists" : true
            }
        }, {
            "checkFields.field2" : {
                "$exists" : true
            }
        }, {
            "checkFields.field3" : {
                "$exists" : true
            }
        }]
    }, {
        "$or" : [{
            "checkFields.user" : "admin"
        }]
    }]
}
*/
collection.find(query);