2016-09-07 28 views
2

我正在使用mongo和nodejs。Mongo +检查现有的多个字段

我有数组列表:

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

我试图让具有数组列表字段的记录数和用户字段等于管理。

样本数据:

[ 
    { 
     "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)领域匹配的计数的行。

+1

请分享您的模式 –

+0

{“_id”:ObjectId(“5796fba32dc0d21e774fa074”),“checkFields”:{“id”:“00124b3a5c31”,“user”:“admin”}} – RSKMR

+0

有任何想法做到这一点? – RSKMR

回答

1

构建一个$or阵列现场检查存在的列表是正确的做法,但假设你在当前的node.js建立可以简化创建查询到:

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

这对于消除多余$or“用户管理”检查,它可以让您同时删除外$and,使生成的查询是:

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

感谢您的留言。条件应该是数组列表中的字段,用户是admin。 – RSKMR

+0

@RSKMR正确,这就是查询所要做的。查询的顶层条款隐式与逻辑与。 – JohnnyHK

+0

非常感谢...;。 – RSKMR

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 
+0

嗨,感谢您的留言。在一个查询中可能获得总场1,场2,场3计数(2 + 1 ++ 0)= 3? – RSKMR

+0

字段名称是否为静态I.e.你会在以后增加更多的字段名称到数组吗?如果它们是固定的,我会再看一次。 – notionquest

+0

它不是一个静态的。数组列表将根据条件进行更改。 – RSKMR

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);