【问题标题】:Combined lookup and embed in the same MongoDB collection depending on root document structure根据根文档结构组合查找并嵌入到同一个 MongoDB 集合中
【发布时间】:2017-12-06 14:35:46
【问题描述】:

我想通过以下方式使用 Mongo 进行条件查找:根文档包含指向 customers 集合的链接 (customerId) 或直接嵌入客户,如下所示:

{
  "_id" : 1,
  "item": "item1",
  "customer": { _id: 1, "name": "Jane Doe" }
},
{
   "_id":  2,
   "item": "item2",
   "customerId": 1
}

客户集合:

{ _id: 1, "name": "Jane Johnson" }

customers 集合存储客户的当前版本;为了保持一致性,items 集合的成员将只包含客户的 ID。但是,如果我想冻结一个项目以便它在某个时间保存其客户的 版本,我会将 customer 直接嵌入到相关的 item 中。

在搜索items 时,我希望它们统一显示(即无论是查找客户还是嵌入客户,它都会显示为嵌入字段): 例如

[{
  "_id" : 1,
  "item": "item1",
  "customer": { _id: 1, "name": "Jane Doe" } // historical version of Jane (embedded)
},
{
   "_id":  2,
   "item": "item2",
   "customer": { _id: 1, "name": "Jane Johnson" } // current version of Jane by lookup
}]

问题 1:这是正确的方法吗?如果不是,处理此类案件的最佳做法是什么? 问题2:如果我的方法是正确的,如何最好地使用聚合框架来实现这一点? 谢谢!

【问题讨论】:

    标签: mongodb join


    【解决方案1】:

    答案:

    1. 是的,您可以使用aggregation framework 实现它,这是一种可能的解决方案(另一种可能的解决方案是在您的程序中实现它)。

    2. 只需使用$lookup(用于从其他集合合并数据)和$project(用于最终结果生成)管道阶段。

    查询示例:

    db.getCollection('items').aggregate([
        {
            $lookup: {
                from: "customers",
                localField: "customerId",
                foreignField: "_id",
                as: "customerData"
            }
        },
        {
            $project: {
                "item": 1,
                "customer": {
                    $cond: {
                        if: {$gt: [{$size: "$customerData"}, 0]},
                        then: {$arrayElemAt: ["$customerData", 0]},
                        else: "$customer"
                    }
                }
           }
        }
    ]);
    

    【讨论】:

      猜你喜欢
      • 2018-12-29
      • 2021-02-16
      • 1970-01-01
      • 1970-01-01
      • 2021-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多