从聚合管道中的集合中减去子文档
Posted
技术标签:
【中文标题】从聚合管道中的集合中减去子文档【英文标题】:Subtract subdocuments from collection in aggregate pipeline 【发布时间】:2015-05-01 13:26:43 【问题描述】:我正在尝试从 mongodb 检索文档并根据条件 (deleted != null
) 从数组中删除一些对象。这是我定位的项目的简化示例:
"_id" : ObjectId("54ec9cac83a214491d2110f4"),
"name" : "my_images",
"images" : [
"ext" : "jpeg",
"type" : "image/jpeg",
"_id" : ObjectId("54f2311026b0cb289ed04188"),
"deleted" : null,
"date_added" : ISODate("2015-02-28T21:20:16.961Z"),
,
"ext" : "jpeg",
"type" : "image/jpeg",
"_id" : ObjectId("54f2314a26b0cb289ed04189"),
"deleted" : ISODate("2015-02-24T15:38:14.826Z"),
"date_added" : ISODate("2015-02-28T21:21:14.910Z"),
,
"ext" : "jpeg",
"type" : "image/jpeg",
"_id" : ObjectId("54f2315526b0cb289ed0418a"),
"deleted" : null,
"date_added" : ISODate("2015-02-28T21:21:25.042Z"),
,
"ext" : "jpeg",
"type" : "image/jpeg",
"_id" : ObjectId("54f2315d26b0cb289ed0418b"),
"deleted" : null,
"date_added" : ISODate("2015-02-28T21:21:33.081Z"),
]
成功的查询将返回相同的结果,但删除了其中一个图像对象,因为它具有 ISODate 而不是 null。像这样:
"_id" : ObjectId("54ec9cac83a214491d2110f4"),
"name" : "my_images",
"images" : [
"ext" : "jpeg",
"type" : "image/jpeg",
"_id" : ObjectId("54f2311026b0cb289ed04188"),
"deleted" : null,
"date_added" : ISODate("2015-02-28T21:20:16.961Z"),
,
"ext" : "jpeg",
"type" : "image/jpeg",
"_id" : ObjectId("54f2315526b0cb289ed0418a"),
"deleted" : null,
"date_added" : ISODate("2015-02-28T21:21:25.042Z"),
,
"ext" : "jpeg",
"type" : "image/jpeg",
"_id" : ObjectId("54f2315d26b0cb289ed0418b"),
"deleted" : null,
"date_added" : ISODate("2015-02-28T21:21:33.081Z"),
]
我尝试使用聚合到 $unwind
图像然后 $match
仅相关图像,但我现在需要重新创建文档,否则它会返回剩余的 3 个“展开”文档。
这是我目前所处的位置:
Collection.aggregate([
$match:
_id: ObjectID(collection_id)
,
$unwind: "$images" ,
$match:
"images.deleted": null
// Next step in the pipeline to
// reconfigure into one document
// goes here
], function (err, result)
if (err)
console.log(err);
return;
console.log(result);
);
有没有办法从剩余的文件中创建一个文档,还是我以完全错误的方式处理这个问题?
谢谢。
【问题讨论】:
【参考方案1】:正如您所提到的,您需要将展开、过滤的文档重新组合回其原始形状。你可以通过$group
做到这一点:
Collection.aggregate([
$match:
_id: ObjectID(collection_id)
,
$unwind: "$images" ,
$match:
"images.deleted": null
,
// Regroup the docs by _id to reassemble the images array
$group:
_id: '$_id',
name: $first: '$name',
images: $push: '$images'
], function (err, result)
if (err)
console.log(err);
return;
console.log(result);
);
【讨论】:
我有类似的东西,但 $first 是我所缺少的。上面的例子有一个非常简化的集合,实际上还有更多的字段。我需要为每个字段使用 $first 还是有办法将它们全部通过(除了将使用 $push 的“图像”)?再次感谢。 @Simon 不,您需要在$group
中明确包含每个字段。以上是关于从聚合管道中的集合中减去子文档的主要内容,如果未能解决你的问题,请参考以下文章