【问题标题】:$lookup when foreign field is an array$lookup 当外部字段是一个数组时
【发布时间】:2020-08-11 20:07:50
【问题描述】:

我有两个收藏。

运动

{
    "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", 
        ]
        },

【问题讨论】:

  • 你是如何初始化$sports_data的?请同时发布该初始化行。
  • 因为您的 foreignField 是一个对象数组,这就是 ID 不匹配的原因。您必须使用较新的 $lookup 语法到 $unwind sports_items $lookup 管道内。
  • slot_divisions 似乎不是一个数组。看来您设法分别将键命名为 "0""1"。另一个文档中的slots 是一个“数组”(PHP 世界以外的人称之为数组)实际上应该看起来像存储在 MongoDB 中的示例。例如,您可以使用"slot_divisions.0.div_id",但这并不重要,因为它始终指向特定的命名键。
  • @AnthonyWinzlet 你能检查更新的查询吗?它仍然无法正常工作
  • $lookup 舞台下方使用。 { $lookup: { from: "sports_items_collection", let: { "slot_id": "$slots.slot_id" }, pipeline: [ { $unwind: "$slot_divisions" }, { $match: { $expr: { $in: [ "$slot_divisions.div_id", "$$slot_id" ] } } } ], as: "sports_data" } }

标签: mongodb laravel mongodb-query aggregation-framework lookup


【解决方案1】:

你可以使用下面的聚合

您可以使用新的$lookup 语法对$lookup 管道内的外部数组$unwind 使用$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
  }}
])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 2018-11-27
    相关资源
    最近更新 更多