Поиск ссылочного документа в массиве вложенных документов - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть две коллекции. Один содержит массив объектов. Этим объектам принадлежит поле с идентификатором документа в другой коллекции. Цель состоит в том, чтобы «заменить» ссылку документом. Звучит просто, но я понятия не имею, как архивировать это.

EG

Коллекция "Продукт"

{ "_id": 1,
  "alias": "ProductA"
},
{ "_id": 2,
  "alias": "ProductC"
}

Коллекция "Заказать "

{ "_id": 5765,
  "cart": [
    {
      "product": 1,
      "qty": 7
    }, {
      "product": 2,
      "qty": 6
    }
  ]
}

Что мне нужно по запросу, это:

{ "_id": 5765,
  "cart": [
    {
      "product": {
        "_id": 1,
        "alias": "ProductA"
      },
      "qty": 7
    }, {
      "product": {
        "_id": 2,
        "alias": "ProductC"
      },
      "qty": 6
    }
  ]
}

Я пробовал простой поиск, но массив будет содержать только продукты. Что мне нужно изменить?

{
    $lookup: {
        from: "products",
        let: {
            tmp: "$cart.product"
        },
        pipeline: [
            {
                $match: {
                    $expr: {
                        $in: ["$_id", "$$tmp"]
                    }
                }
            }
        ],
        as: "cart.product"
    }
}

Спасибо за вашу помощь.

1 Ответ

1 голос
/ 16 апреля 2020

Я добавил новый этап $addFields для преобразования вывода из этапа $lookup - он получает желаемый результат:

db.order.aggregate([
{
    $lookup: {
        from: "product",
        let: {
            tmp: "$cart.product"
        },
        pipeline: [
            {
                $match: {
                    $expr: {
                        $in: ["$_id", "$$tmp"]
                    }
                }
            }
        ],
        as: "products"
    }
},
{ 
    $addFields: {
         cart: {
             $map: {
                 input: "$cart", as: "ct",
                 in: {
                     product: {
                         $arrayElemAt: [ 
                             { $filter: {
                                   input: "$products", as: "pr",
                                   cond: {
                                      $eq: [ "$$ct.product", "$$pr._id" ]
                                   }
                              }
                          }, 0 ]
                     },
                     qty: "$$ct.qty"
                 }
             }
         }
    }
}
] ).pretty()
...