通过条件查询优化Mongo聚合查询

时间:2019-03-18 11:39:56

标签: mongodb mongodb-query aggregation-framework

所以我有一个收藏集事件,如下所示:

事件

{
    "_id" : ObjectId("5c8f4d3bbbf999bd7d1cc11c"),
    "category" : "Comment",
    "reference_field" : ObjectId("5c8f4ba4bbf999bbb056984f"), // Object id of a document in the COMMENT collection
    "deleted_reference_field" : "Not Deleted",
    "summary" : "Some string"
},
{
    "_id" : ObjectId("5c8b7e6dbbf99995bdcb37ac"),
    "category" : "Comment",
    "reference_field" : ObjectId("5c8b3fe9bbf9997e1f18c816"), // object id of a document in the PROJECT collection
    "deleted_reference_field" : "Project",
    "summary" : "Here is a new comment!"
}

如您所见,event集合的两个文档都引用了不同的集合。这由deleted_reference_field属性确定。

  • 如果其值为未删除,则reference_field包含引用Comment集合的objectId。

  • 如果值为Project或任何此类字符串,则reference_field包含应引用的集合的对象ID。在此示例中,它引用了Project集合。

我需要执行$lookup来填充相应的reference_field。为此,我需要某种if-else语句,以便可以指定要查看的集合。

我的聚合管道应该做什么的伪代码:

Group all documents by Category
if reference_field is "Not Deleted"
then $lookup on Collection mentioned in Category
else $lookup on the deleted_reference_field Collection (Project in this case)

当前的汇总代码: 我当前的管道根本没有效率。每当我使用不同的类别和不同的deleted_reference_field值时,我就会通过 N 个文档。看起来像这样:

db.events.aggregate([
    {
    "$facet": {
        "comments": [
            {"$match": {"category": "Comment"}},
            {"$match": {"deleted_reference_field": "Not Deleted"}},
            {
                "$lookup": {
                    "from": "comment",
                    "localField": "reference_field",
                    "foreignField": "_id",
                    "as": "Comments",
                }
            },
            {"$unwind": "$Comments"},
            {"$match": {"Comments.project_id": bson.ObjectId(project_id)}},
        ],
        "deleted_comments": [
            {"$match": {"category": "Comment"}},
            {"$match": {"deleted_reference_field": "Project"}},
            {"$match": {"reference_field": bson.ObjectId(project_id)}},
        ]}
    }

])

如您所见,有2个“存储桶”,一个用于评论,一个用于 deleted_comemnts 。因此,每次创建存储桶时,我都会遍历所有文档以筛选出类别为“注释”和deleted_reference_field为“未删除”或“项目”的文档。大约有7-8个类别(我只显示了注释),我遵循了相同的过程,因此被证明效率很低。

因此,我想通过基于 Category (类别)对所有文档进行分组,并根据deleted_reference_field中的值对它们进行分组,以减少这种庞大的复杂性。

简而言之:

  

由于完全从不同的集合中获取文档,我如何建立一个可以执行条件查找的聚合管道。

0 个答案:

没有答案