首页 > 解决方案 > $lookup 当外部字段是一个数组

问题描述

我有两个系列。

运动

{
    "id" : 1,
    "name" : "Football",
    "slots" : {
    "0" : {
        "div_id" : 1,
        "description" : "5x5"
    },
    "1" : {
        "div_id" : 2,
        "description" : "7x7"
    }
 })

预订

{
    "id" : 1,
    "spot" : 'SPOT1',
    "date" : ISODate("2018-11-13T10:04:45.000Z"),
    "slots" : [ 
        {
            "booking_id" : 142,
            "slot_id" : 23,
             ...
        }]
}

我想显示预订详情。加入两个系列时,无法获取运动详细信息。

我试过这个:

     $bookData  =   Booking::raw(function($collection) use($request) {
                   ....
            return $collection->aggregate([
               ['$lookup' => ['from'=>'spots', 'localField'=>'spot_id', 'foreignField'=>'id', 'as'=>'spot_data']],
               ['$lookup' => ['from'=>'sports_items', 'localField'=>'slots.slot_id', 'foreignField'=>'slot_divisions.div_id', 'as'=>'sports_data']],
               ['$unwind'  =>'$slots'],
               ['$project' => [
                    'booking_id'=>'$slots.booking_id',
                    'date'=>'$date',
                    'sports_data.item_name'=>'$sports_data.item_name',
                    'sports_data.item_icon'=>'$sports_data.item_icon',
                ]],

            ]);
        });

我得到了回应:

"sports_data": []

有人可以帮我弄这个吗?

更新: 我尝试如下查找管道衬里。但仍然是空的结果

 ['$lookup' => ['from'=>'sports_items', 'localField'=>'slots.slot_id', 'foreignField'=>'slot_divisions.div_id', 'as'=>'sports_data']],   

变成

      ['$lookup' => [
                    'from'=>'sports_items_collection',
                     'pipeline' =>[
                         ['$unwind'  =>'$slot_divisions'],
                         ['$match'=>["slots.slot_id"=>['$eq'=> ["slot_divisions.div_id"]]]]
                     ],
                     'as'=>'sports_data'
                   ]],

我的预期输出是:

  "booking": [
        {
            "booking_id": "5be015bd870565038c7660f3",
            "date": "2018-11-13 15:34:45",
            "sports_data": [
        "item_name" : "Football",
        "item_icon" : "ps_icon_football.png", 
        ]
        },

标签: mongodblaravelmongodb-queryaggregation-frameworklookup

解决方案


您可以使用以下聚合

您可以对管道内的外部数组使用新$lookup语法,然后可以轻松使用$unwind$lookup$matchids

db.bookings.aggregate([
  { "$lookup": {
    "from": "sports",
    "let": { "slot_id": "$slots.slot_id" },
    "pipeline": [
      { "$unwind": "$slot_divisions" },
      { "$match": { "$expr": { "$in": ["$slot_divisions.div_id", "$$slot_id"] }}},
      { "$project": { "item_name": 1, "item_icon": 1 }}
    ],
    "as": "sports_data"
  }},
  { "$project": {
    "booking_id": { "$arrayElemAt": ["$slots.booking_id", 0] },
    "date": 1,
    "sports_data": 1
  }}
])

推荐阅读