从聚合管道中的集合中减去子文档

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 中明确包含每个字段。

以上是关于从聚合管道中的集合中减去子文档的主要内容,如果未能解决你的问题,请参考以下文章

mongoDB表与表的关系及聚合管道查询

MongoDB - 聚合查询

mongodb聚合命令

在基于文档的聚合管道中使用 $merge 不起作用

MongoDB 聚合管道(Aggregation Pipeline)

如何使用聚合管道从 mongodb 中的当前字段中减去更新?