所以我有一个收藏集事件,如下所示:
事件
{
"_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
中的值对它们进行分组,以减少这种庞大的复杂性。
简而言之:
由于完全从不同的集合中获取文档,我如何建立一个可以执行条件查找的聚合管道。