【问题标题】:Get result from three collection in mongodb从 mongodb 中的三个集合中获取结果
【发布时间】:2018-06-20 11:03:02
【问题描述】:

我有三个集合包含如下数据,

客户集合

{ 
    "_id" : ObjectId("5a058e316803fafd127b23c9"), 
    "client_name" : "client A", 
    "client_status" : "A"
}
{ 
    "_id" : ObjectId("5a058e316803fafd127b23cb"), 
    "client_name" : "client B", 
    "client_status" : "A"
}

池集合

{ 
    "_id" : ObjectId("5a0e76f66803fa530a7b23d4"), 
    "pool_name" : "pool A", 
    "pool_status" : "A", 
    "client_id" : ObjectId("5a058e316803fafd127b23c9"), 
    "schools" : [
        ObjectId("5a0e742b6803faa6097b2462"), 
        ObjectId("5a0e742b6803faa6097b2464")
    ]
}
{ 
    "_id" : ObjectId("5a0e76f76803fa530a7b2402"), 
    "pool_name" : "pool B", 
    "pool_status" : "A", 
    "client_id" : ObjectId("5a058e316803fafd127b23c9"), 
    "schools" : [
        ObjectId("5a0e742b6803faa6097b2463")
    ]
}
{ 
    "_id" : ObjectId("5a0e76f76803fa530a7b23f6"), 
    "pool_name" : "pool C", 
    "pool_status" : "A", 
    "client_id" : ObjectId("5a058e316803fafd127b23cb"), 
    "schools" : [
        ObjectId("5a7aa1476803fa1f117b23d1")
    ]
}

学校收藏

{ 
    "_id" : ObjectId("5a0e742b6803faa6097b2462"), 
    "school_name" : "School A", 
    "school_status" : "A"
}
{ 
    "_id" : ObjectId("5a0e742b6803faa6097b2463"), 
    "school_name" : "School B", 
    "school_status" : "A"
}
{ 
    "_id" : ObjectId("5a0e742b6803faa6097b2464"), 
    "school_name" : "School C", 
    "school_status" : "A"
}
{ 
    "_id" : ObjectId("5a7aa1476803fa1f117b23d1"), 
    "school_name" : "School D", 
    "school_status" : "A"
}

从这个集合中,我需要为像下面这样的客户获取池的学校列表。

**Output**

{
    "_id" : ObjectId("5a058e316803fafd127b23c9"),
    "client_name" : "client A", 
    "client_status" : "A"
    "pools" : [
        {
            "_id" : ObjectId("5a0e76f66803fa530a7b23d4"), 
            "pool_name" : "pool A", 
            "pool_status" : "A",
            'schools' => [
                { 
                    "_id" : ObjectId("5a0e742b6803faa6097b2462"), 
                    "school_name" : "School A", 
                    "school_status" : "A"
                },
                { 
                    "_id" : ObjectId("5a0e742b6803faa6097b2464"), 
                    "school_name" : "School C", 
                    "school_status" : "A"
                },
            ]
        },
        {
            "_id" : ObjectId("5a0e76f76803fa530a7b2402"), 
            "pool_name" : "pool B", 
            "pool_status" : "A",
            "schools" : [
                { 
                    "_id" : ObjectId("5a0e742b6803faa6097b2463"), 
                    "school_name" : "School B", 
                    "school_status" : "A"
                }   
            ]
        }
    ]
},
{
    "_id" : ObjectId("5a058e316803fafd127b23cb"), 
    "client_name" : "client B",
    "client_status" : "A"
    "pools" : [
        {
            "_id" : ObjectId("5a0e76f76803fa530a7b23f6"), 
            "pool_name" : "pool C", 
            "pool_status" : "A",
            "schools" : [
                { 
                    "_id" : ObjectId("5a7aa1476803fa1f117b23d1"), 
                    "school_name" : "School D", 
                    "school_status" : "A"
                }
            ]
        }
    ]
}

【问题讨论】:

    标签: mongodb collections aggregation-framework aggregate


    【解决方案1】:

    你可以试试下面的聚合

    Mongodb 3.6 引入了嵌套的$lookup 管道......所以你不需要像上面那样使用另一个$lookup 阶段......你可以在这里使用嵌套的$lookup 管道

    Client.aggregate([
      { "$match": { 'client_status': 'A' } },
      { "$lookup": {
        "from": Pool.collection.name,
        "let": { "client_id": "$_id" },
        "pipeline": [
          { "$match": { "$expr": { "$eq": [ "$client_id", "$$client_id" ] } } },
          { "$addFields": {
            "schools": {
              "$ifNull": ["$schools", []]
            }
          }}
          { "$lookup": {
            "from": Schools.collection.name,
            "let": { "schools": "$schools" },
            "pipeline": [
              { "$match": { "$expr": { "$in": [ "$_id", "$$schools" ] } } }
            ],
            "as": "schools"
          }}
        ],
        "as": "pools"
      }}
    ])
    

    啰嗦的解释可以去$lookup multiple levels without $unwind?

    【讨论】:

    • 这会返回一个错误 - Mongo 服务器错误 (MongoCommandException): 命令失败,错误 40081: '$in 需要一个数组作为第二个参数,在服务器 localhost:27017 上找到:缺失'。完整的响应是: { "ok" : 0.0, "errmsg" : "$in 需要一个数组作为第二个参数,发现:缺失", "code" : NumberInt(40081), "codeName" : "Location40081" }
    • 这是因为您的 schools 集合中的某处缺少您的 schools 密钥...尝试使用 schools: [] 更新您的集合
    • @Shijin 检查更新的答案...我在那边添加了$ifNull条件...现在它肯定会工作
    • 如何获取每个客户的学校数量
    • @Shijin Hiii,如果您有新的疑问,请提出一个新问题...顺便说一句,您可以使用$size 运算符检查学生数组的长度
    猜你喜欢
    • 2017-03-25
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    • 2021-07-01
    • 1970-01-01
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多