поэтому у меня есть коллекция событий , которая выглядит следующим образом:
событий
{
"_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
.
Если значение Project
или любая такая строка, то reference_field
содержит идентификатор объекта коллекции, на которую он должен ссылаться.В этом примере это относится к коллекции 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)
Текущий код агрегации: Мой текущий конвейер не эффективен.Я собираюсь, хотя N документы, каждый раз, когда у меня есть другая категория и другое значение deleted_reference_field
.Выглядит это так:
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_reference_field
как «Не удалено» или «Проект».Есть около 7-8 категорий (я показал только Комментарий), для которых я следовал тому же процессу, поэтому оказался очень неэффективным.
Следовательно, я хочу уменьшить эту огромную сложность, сгруппировав все документы на основе Категория и дополнительно сгруппировав их на основе значения в deleted_reference_field
.
Вshort:
Как построить конвейер агрегации, который может выполнять условный поиск из-за того, что документы извлекаются из разных коллекций целиком.