使用JavaScript在mongoDb中查询

这是我在DB中的示例文档。

{ "_id":1, "object":{ "featureOne":true, "featureTwo":false, "featureThree":false, "featureFour":false } }, { "_id":2, "object":{ "featureOne":false, "featureTwo":false, "featureThree":false, "featureFour":false } }, { "_id":3, "object":{ "featureOne":true, "featureTwo":false, "featureThree":false, "featureFour":false } } 

我想在一个查询中使用“featureOne”:true和另一个使用“featureOne”:false的对象。 我有使用特定的键和价值find数据的知识。 但是我怎样才能在一个单一的查询中使用相同的真值和错误值的键来获取数据。 目前我正在使用这个代码

 db.collection(collectionName).find({"featureOne":true, {limit:1}).toArray(function(err, results) { db.collection(collectionName).find("featureOne":,false{limit:2}).toArray(function(err,res { console.log(results,res); }); }); 

有没有更好的办法来实现这一目标?

你可以用聚合框架来实现它。

您可以使用$ group和$ project阶段(如Clement Amarnath答案中所述),但是如果您需要对数据收集阶段进行更多的控制,则可以使用:

  • $ facet – 通过子聚合pipe道收集数据。
  • $匹配 – 设置文档filter的标准。
  • $ limit – 定义可以获取的文档的最大数量(如果要随机化结果,则使用$ sample )。
  • $ addFields – 将结果合并到一个元素(数组)中。
  • $ unwind – 将结果数组分成独立的文档。
  • $ replaceRoot – 更改文档根元素。

示例代码:

 db.collection.aggregate([ { $facet: { "result1": [ {$match: {"object.featureOne": true}}, {$limit: 1} ], "result2": [ {$match: {"object.featureOne": false}}, {$limit: 1} ] } }, {$addFields: {"results": [{$arrayElemAt: ["$result1", 0]}, {$arrayElemAt: ["$result2", 0]}]}}, {$unwind: "$results"}, {$replaceRoot: {newRoot: "$results"}} ]) 

使用$ aggregate ,我们可以做到这一点

查询来实现结果

 db.collection.aggregate([ {$group:{"_id": {"featureOne":"$object.featureOne"}, object:{$first:"$object"}, origId:{$first:"$_id"}} }, {$project:{_id:"$origId", object:"$object"}} ]) 

$ group和$ project被用来得到这个结果

样本数据

 { "_id" : 1, "object" : { "featureOne" : true, "featureTwo" : false, "featureThree" : false, "featureFour" : false } } { "_id" : 2, "object" : { "featureOne" : false, "featureTwo" : false, "featureThree" : false, "featureFour" : false } } { "_id" : 3, "object" : { "featureOne" : true, "featureTwo" : false, "featureThree" : false, "featureFour" : false } } { "_id" : 4, "object" : { "featureOne" : true, "featureTwo" : true, "featureThree" : false, "featureFour" : true } } { "_id" : 5, "object" : { "featureOne" : false, "featureTwo" : false, "featureThree" : false, "featureFour" : true } } { "_id" : 6, "object" : { "featureOne" : true, "featureTwo" : true, "featureThree" : false, "featureFour" : false } } 

在这个数据上执行$ group之后 ,我们会得到\

 { "_id" : { "featureOne" : false }, "object" : { "featureOne" : false, "featureTwo" : false, "featureThree" : false, "featureFour" : false }, "origId" : 2 } { "_id" : { "featureOne" : true }, "object" : { "featureOne" : true, "featureTwo" : false, "featureThree" : false, "featureFour" : false }, "origId" : 1 } 

为了使它看起来像原来的集合,我们必须使用$项目,执行$项目pipe道上的结果后,我们将得到

 { "_id" : 2, "object" : { "featureOne" : false, "featureTwo" : false, "featureThree" : false, "featureFour" : false } } { "_id" : 1, "object" : { "featureOne" : true, "featureTwo" : false, "featureThree" : false, "featureFour" : false } } 

我认为你的方法很好。 但在这两种情况下,您的限制可以是1例如,在Mongoose中,您可以调用findOne,但是对于官方驱动程序,我认为您的方法是正确的。

如果你想避免这两个调用,你可以提取集合的所有元素,并通过代码循环,直到你得到每个值之一。 如果您的collections中没有多个文档,则可能比其他方法更高效。