Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我如何执行嵌套的";加入;(加入3个或更多集合)在MongoDB聚合管道中?_Mongodb_Nosql_Aggregation Framework_Nosql Aggregation - Fatal编程技术网

我如何执行嵌套的";加入;(加入3个或更多集合)在MongoDB聚合管道中?

我如何执行嵌套的";加入;(加入3个或更多集合)在MongoDB聚合管道中?,mongodb,nosql,aggregation-framework,nosql-aggregation,Mongodb,Nosql,Aggregation Framework,Nosql Aggregation,假设MongoDB中有3个假设集合:客户,订单,以及订单项 每个客户都有多个订单,每个订单都有多个订单项 以下是这3个集合的一些示例数据: 客户 命令 订单项 期望结果 我如何编写聚合管道,使返回的结果看起来像这样 [ { customer_id: 1, name: "Jim Smith", email: "jim.smith@example.com" orders: [

假设MongoDB中有3个假设集合:
客户
订单
,以及
订单项

每个客户都有多个订单,每个订单都有多个订单项

以下是这3个集合的一些示例数据:

客户 命令 订单项 期望结果 我如何编写聚合管道,使返回的结果看起来像这样

[
    {
        customer_id: 1,
        name: "Jim Smith",
        email: "jim.smith@example.com"
        orders: [
            {
                order_id: 1,
                items: [
                    {
                        name: "Foo",
                        price: 4.99
                    },
                    {
                        name: "Bar",
                        price: 17.99
                    }
                ]
            },
            {
                order_id: 2,
                items: [
                    {
                        name: "baz",
                        price: 24.99
                    }
                ]
            }
        ]
    },
    {
        customer_id: 2,
        name: "Bob Jones",
        email: "bob.jones@example.com"
        orders: []
    }
]
使用

  • $lookup
    带有
    订单
    集合,
    • let
      ,定义来自主集合的变量
      customer\u id
      ,使用
      $$
      $$customer\u id
      一样在管道内访问此参考变量
    • pipeline
      可以像在根级别管道中一样添加管道阶段
    • $expr
      每当我们匹配内部字段时,它都需要表达式匹配条件,因此
      $$customer\u id
      是在
      let
      中声明的父集合字段,
      $customer\u id
      是子集合/当前集合的字段
  • $lookup
    orderitems
    集合


提示:

在NoSQL中有几个连接被认为是不好的做法,我建议如果您可以将订单项作为数组添加到orders集合中,您可以为orderitems保存一个连接过程,请参阅中的改进版本


您能否解释一下
$lookup
管道中的
$match
阶段是如何工作的,以及为什么需要它?在本例中,如果您完全删除
$match
阶段,结果仍然相同。我已进一步更新了详细信息。您将从附加的$lookup参考链接获得更多帮助,是$match对于根据特定字段加入参考文档是必需的。如果您完全删除$match阶段,结果仍然相同,因为集合中没有其他文档,请添加一些不是父文档引用的虚拟文档。谢谢,我接受了您的回答。最后一件事,有点不相关:通常认为规范化Mongo数据的方式不好,因为它可能需要像这样的几个连接吗?我在这里描述的示例对于SQL来说似乎完全正常,但我不确定是否有更好的方法在Mongo中进行操作。我在回答中添加了一个技巧。
[
    {
        order_id: 1,
        customer_id: 1
    },
    {
        order_id: 2,
        customer_id: 1
    }
]
[
    {
        order_item_id: 1,
        name: "Foo",
        price: 4.99,
        order_id: 1
    },
    {
        order_item_id: 2,
        name: "Bar",
        price: 17.99,
        order_id: 1
    },
    {
        order_item_id: 3,
        name: "baz",
        price: 24.99,
        order_id: 2
    }
]
[
    {
        customer_id: 1,
        name: "Jim Smith",
        email: "jim.smith@example.com"
        orders: [
            {
                order_id: 1,
                items: [
                    {
                        name: "Foo",
                        price: 4.99
                    },
                    {
                        name: "Bar",
                        price: 17.99
                    }
                ]
            },
            {
                order_id: 2,
                items: [
                    {
                        name: "baz",
                        price: 24.99
                    }
                ]
            }
        ]
    },
    {
        customer_id: 2,
        name: "Bob Jones",
        email: "bob.jones@example.com"
        orders: []
    }
]
db.customers.aggregate([
  {
    $lookup: {
      from: "orders",
      let: { customer_id: "$customer_id" },
      pipeline: [
        { $match: { $expr: { $eq: ["$$customer_id", "$customer_id"] } } },
        {
          $lookup: {
            from: "orderitems",
            localField: "order_id",
            foreignField: "order_id",
            as: "items"
          }
        }
      ],
      as: "orders"
    }
  }
])