我有一个收集用户如下:
{ "_id" : ObjectId("51780f796ec4051a536015cf"), "userId" : "John" }
{ "_id" : ObjectId("51780f796ec4051a536015d0"), "userId" : "Sam" }
{ "_id" : ObjectId("51780f796ec4051a536015d1"), "userId" : "John1" }
{ "_id" : ObjectId("51780f796ec4051a536015d2"), "userId" : "john2" }
现在我正在尝试编写一个代码,该代码可以在用户提供的id已经存在于DB中的情况下向用户提供userId的建议。在同一个例程中,我只是将值1到5附加到例如用户选择userId为John的情况下,需要在数据库中检查Id的建议用户名数组将如下所示
[John,John1,John2,John3,John4,John5].
现在我只想针对Db执行它,并找出DB中不存在哪些建议值。因此,我不想选择任何文档,而是选择建议数组中的值,这些值对于用户集合是不存在的。
任何指针都非常感谢。
答案 0 :(得分:0)
这里的一般方法是,您希望找到集合中已存在的“userId”的“不同”值。然后,将这些与输入选择进行比较,以查看差异。
var test = ["John","John1","John2","John3","John4","John5"];
var res = db.collection.aggregate([
{ "$match": { "userId": { "$in": test } }},
{ "$group": { "_id": "$userId" }}
]).toArray();
res.map(function(x){ return x._id });
test.filter(function(x){ return res.indexOf(x) == -1 })
最终结果是在初始输入中不匹配的userId:
[ "John2", "John3", "John4", "John5" ]
主运算符有$in
,它以数组作为参数,并将这些值与指定字段进行比较。 .aggregate()
方法是最好的方法,.distinct()
方法中有一个简写的mapReduce包装器,它直接生成数组中的值,删除对.map()
之类的函数的调用以去除输出给定键的值:
var res = db.collection.distinct("userId",{ "userId": { "$in": test } })
它应该运行得特别慢,特别是在大型集合上。
另外,请不要忘记为您的“userId”编制索引,并且您可能希望此选项为“唯一”,因此您只需要 $match
或.find()
结果:
var res = db.collection.find({ "$in": test }).toArray()