我没有设置 mongoose 来使用节点执行此操作,但您也可以使用 2.2 中的新聚合框架获得您想要的结果 - 这是一个可以为您提供所需结果的示例。首先,我的示例文档如下所示:
> db.foo.findOne()
{
"_id" : ObjectId("50472eb566caf6af6108de02"),
"items" : [
1,
2,
3,
45,
4,
67,
9,
4
]
}
为了达到你想要的,我这样做了:
> db.foo.aggregate(
{$match : {"_id": ObjectId("50472eb566caf6af6108de02")}},
{$unwind : "$items"},
{$match : {"items": {$in : [1, 67, 9]}}},
{$group : {_id : "$_id", items : { $push : "$items"}}},
{$project : {_id : 0, items : 1}}
)
{
"result" : [
{
"_id" : ObjectId("50472eb566caf6af6108de02"),
"items" : [
1,
67,
9
]
}
],
"ok" : 1
}
为了解释,我将逐行详细说明:
{$match : {"_id": ObjectId("50472eb566caf6af6108de02")}}
这是相当明显的——它基本上等同于常规查询的查找条件,结果被传递到管道中的下一步进行处理。这是可以使用索引等的部分。
{$unwind : "$items"}
这将爆炸数组,创建一个文档流,数组的每个元素都有一个。
{$match : {"items": {$in : [1, 67, 9]}}}
第二个匹配将只返回列表中的文档,基本上将文档流减少到三个结果集。
{$group : {_id : "$_id", items : { $push : "$items"}}}
我们希望我们的输出是一个数组,所以我们必须撤消上面的展开,因为我们已经选择了我们想要的项目,使用 _id 作为分组的键。注意:如果有多个匹配项,这将具有重复值,如果您想要一个唯一列表,您将使用$addToSet
而不是$push
{$project : {_id : 1, items : 1}}
最后,这个投影并不是真正需要的,但我将它包括在内以说明功能 - 如果您愿意,您可以选择不返回 _id 等。