MongoDB: эффективный способ объединения коллекций внутри фасета - PullRequest
0 голосов
/ 16 января 2020

У меня есть агрегат, который можно суммировать в:

db.getCollection('originalCollection').aggregate([
    $match: { //some filters }
    $project: { //some transformations}
    $facet: {
        "collectionA": [ //some transformation steps ],
        "collectionB": [ //some other transformation steps ]
    }
...

Теперь я хочу сделать SQL -подобное объединение с коллекциями A и B с использованием поля id. Например, если у меня есть этот документ в коллекции A:

{
    id: "A"
    property1: "a value"
}

и этот документ в коллекции B:

{
    id: "A"
    property2: "other value"
}

Полученная коллекция должна содержать:

{
   id: "A",
   property1: "a value",
   property2: "other value"
}

В качестве следующего шага агрегации я попытался использовать $map в коллекции A, которая использует $filter для сопоставления документа с тем же идентификатором в коллекции B, но ОЧЕНЬ медленно:

{
    "$project": {
        "tmpResult": {
            "$map": {
                "input": "$collectionA",
                "as": "collectionADocument",
                "in": {
                    "property1": "$$collectionADocument.property1",
                    "property2": {
                        "$arrayElemAt": [
                            {
                                "$filter": {
                                    "input": "$collectionB",
                                    "cond": {
                                        "$eq": [
                                            "$$collectionADocument.id",
                                            "$$this.id"
                                        ]
                                    }
                                }
                            },
                            0
                        ]
                    }
                }
            }
        }
    }
}

Какой самый быстрый способ добиться объединения в две коллекции в фасете? Заранее спасибо!

1 Ответ

0 голосов
/ 16 января 2020

Почему бы вам не использовать $ lookup, оператор $ lookup, добавленный в конвейер агрегации, по сути идентичен левому внешнему объединению:

https://docs.mongodb.org/master/reference/operator/aggregation/lookup/#pipe ._ S_lookup

из документов,

{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}

Для вашего примера это может быть что-то вроде ниже,


db.B.aggregate({
   $lookup:
     {
       from: "A",
       localField: "id",
       foreignField: "id",
       as: "AB"
     }
})

...