mongodb 中的 $lookup 嵌套数组

Posted

技术标签:

【中文标题】mongodb 中的 $lookup 嵌套数组【英文标题】:$lookup nested array in mongodb 【发布时间】:2018-05-29 12:41:31 【问题描述】:

我正在为 MongoDB 中新的(可爱的)lookup 运算符而苦苦挣扎。我有 3 个收藏:

艺术家

 
    "_id" : ObjectId("5b0d2b2c7ac4792df69a9942"), 
    "name" : "Dream Theater", 
    "started_in" : NumberInt(1985), 
    "active" : true, 
    "country" : "US", 
    "current_members" : [
        ObjectId("5b0d2a7c7ac4792df69a9941")
    ], 
    "previous_members" : [
        ObjectId("5b0d2bf57ac4792df69a9954")
    ], 
    "albums" : [
        ObjectId("5b0d16ee7ac4792df69a9924"), 
        ObjectId("5b0d47667ac4792df69a9994")
    ], 
    "genres" : [
        "prog metal", 
        "prog rock"
    ]

专辑

 
    "_id" : ObjectId("5b0d16ee7ac4792df69a9924"), 
    "title" : "Images and words", 
    "released" : ISODate("1992-07-07T00:00:00.000+0000"), 
    "songs" : [
        ObjectId("5b0d15ab7ac4792df69a9916"), 
        ObjectId("5b0d15ee7ac4792df69a991e"), 
        ObjectId("5b0d2db37ac4792df69a995d"), 
        ObjectId("5b0d2dbe7ac4792df69a995e"), 
        ObjectId("5b0d2dcb7ac4792df69a995f"), 
        ObjectId("5b0d2dd87ac4792df69a9960"), 
        ObjectId("5b0d2de27ac4792df69a9961"), 
        ObjectId("5b0d2dec7ac4792df69a9962")
    ], 
    "type" : "LP"

 
    "title" : "Awake", 
    "released" : ISODate("1994-10-04T00:00:00.000+0000"), 
    "songs" : [
        ObjectId("5b0d470d7ac4792df69a9991")
    ], 
    "type" : "LP", 
    "_id" : ObjectId("5b0d47667ac4792df69a9994")

歌曲

 
    "_id" : ObjectId("5b0d15ab7ac4792df69a9916"), 
    "title" : "Pull me under"

 
    "_id" : ObjectId("5b0d15ee7ac4792df69a991e"), 
    "title" : "Another day"

 
    "title" : "Take the time", 
    "_id" : ObjectId("5b0d2db37ac4792df69a995d")

 
    "title" : "Surrounded", 
    "_id" : ObjectId("5b0d2dbe7ac4792df69a995e")

 
    "title" : "Metropolis - part I", 
    "_id" : ObjectId("5b0d2dcb7ac4792df69a995f")

 
    "title" : "Under a glass moon", 
    "_id" : ObjectId("5b0d2dd87ac4792df69a9960")

 
    "title" : "Wait for sleep", 
    "_id" : ObjectId("5b0d2de27ac4792df69a9961")

 
    "title" : "Learning to live", 
    "_id" : ObjectId("5b0d2dec7ac4792df69a9962")

 
    "title" : "6:00", 
    "_id" : ObjectId("5b0d470d7ac4792df69a9991")

我可以轻松地与$lookup 进行聚合以获取详细的albums 数组,但是如何在相应的相册中也获取详细的songs? 我想扩展以下查询:

db.artists.aggregate([ 
    $lookup: 
           from: "albums",
           localField: "albums",    
           foreignField: "_id",
           as: "albums"
    
]).pretty()

【问题讨论】:

【参考方案1】:

如果你有 mongodb 版本 3.6 那么你可以尝试嵌套 $lookup 聚合...

db.collection.aggregate([
   "$lookup": 
    "from": Albums.collection.name,
    "let":  "albums": "$albums" ,
    "pipeline": [
        "$match":  "$expr":  "$in": [ "$_id", "$$albums" ]   ,
        "$lookup": 
         "from": Songs.collection.name,
         "let":  "songs": "$songs" ,
         "pipeline": [
            "$match":  "$expr":  "$in": [ "$_id", "$$songs" ]   
         ],
         "as": "songs"
       
     ],
     "as": "albums"
  
 ])

而冗长的解释可以通过$lookup multiple levels without $unwind?

或者如果你有 3.6

之前的 mongodb 版本
db.collection.aggregate([
   "$lookup": 
    "from": Albums.collection.name,
    "localField": "albums",
    "foreignField": "_id",
    "as": "albums"
  ,
   "$unwind": "$albums" ,
   "$lookup": 
    "from": Songs.collection.name,
    "localField": "albums.songs",
    "foreignField": "_id",
    "as": "albums.songs",
  ,
   "$group": 
    "_id": "$_id",
    "name":  "$first": "$name" ,
    "started_in":  "$first": "$started_in" ,
    "active":  "$first": "$active" ,
    "country":  "$first": "$country" ,
    "albums": 
      "$push": 
        "_id": "$albums._id",
        "title": "$albums.title",
        "released": "$albums.released",
        "type": "$albums.type",
        "songs": "$albums.songs"
      
    
  
])

【讨论】:

我有 Mongo 3.6,第一个查询效果很好!是否可以在同一查询中执行其他字段?例如current_members 指向Members 集合 @vicusbass 您可以在let 表达式中定义更多变量,就像albumssongs 一样 @vicusbass 我认为您需要再经历一个$lookup 阶段才能获得更多人口 嗨 Ashish,你能解决这个问题吗***.com/questions/50586276/…

以上是关于mongodb 中的 $lookup 嵌套数组的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 聚合 - 我如何“$lookup”嵌套文档“_id”?

MongoDB $lookup 仅替换对象数组中的 ID

Mongodb Lookup 无法正常工作

MongoDb:使用 $lookup 查找深度嵌套的对象

MongoDb:使用 $lookup 查找深度嵌套的对象

mongoDB对嵌套对象数组的聚合查找