【问题标题】:MongoDB: Joining collections into single document [duplicate]MongoDB:将集合加入单个文档[重复]
【发布时间】:2016-12-01 09:18:19
【问题描述】:

我正在寻找有关联接的一些信息以及它们在MongoDB 中的行为方式。虽然我很欣赏 NoSQL 数据库背后的强大功能是将所有信息存储在文档中,并且该文档包含尽可能多的信息,这样您就不必进行多次查询

不过,我也明白在某些情况下,您可能希望最大限度地减少数据重复,从而最大限度地降低一致性问题的风险。

使用文档引用时,有什么方法可以返回单个文档吗?我尝试了$lookup 函数,虽然它确实返回了正确的结果,但它为每个数组条目返回一个文档。

假设如下结构:

客户:

{
    _id: ObjectId("578d706916f07969c4b0cad1"),
    name: "fred",
    orders: [ObjectId("578d706916f07969c4b0cad2"),ObjectId("578d706916f07969c4b0cad3")]
}

订单:

{
    _id: ObjectId("578d706916f07969c4b0cad2"),
    date: xxxx,
    items: [a,b,c,d]
},
{
    _id: ObjectId("578d706916f07969c4b0cad2"),
    date: xxxx,
    items: [x,y,z]
}

使用查找,我可以获得 2 个文档的结果,每个订单一个附加了客户数据,但是我正在寻找一个带有数组或订单信息的文档 - embedded document。即以下结构

{
    _id: ObjectId("578d706916f07969c4b0cad1"),
    name: "fred",
    orders: [
        {
            _id: ObjectId("578d706916f07969c4b0cad2"),
            date: xxxx,
            items: [a,b,c,d]
        },
        {
            _id: ObjectId("578d706916f07969c4b0cad2"),
            date: xxxx,
            items: [x,y,z]
        }]
}

这在MongoDB 内可能吗?或者join 进程是否与 SQL 数据库非常匹配,以至于您在尝试连接数据时总是会返回重复的客户信息?我知道数据可以在node 等应用程序中转换为单个文档,但是从编写查询的方式来看,是否可以将其返回预格式化?

【问题讨论】:

    标签: mongodb nosql aggregation-framework


    【解决方案1】:

    您可以执行单个aggregation 来获得该结果。 mongo$lookup文档的一部分显示how to lookup with an array

    给定以下集合:

    db.user.insert({
        name: "fred",
        orders: [ObjectId("578d706916f07969c4b0cad2"),ObjectId("578d706916f07969c4b0cad3")]
    })
    db.order.insert({
        _id: ObjectId("578d706916f07969c4b0cad2"),
        date: ISODate("2012-12-20T06:01:17.171Z"),
        items: ["a","b","c","d"]
    })
    
    db.order.insert({
        _id: ObjectId("578d706916f07969c4b0cad3"),
        date: ISODate("2012-12-19T06:01:17.171Z"),
        items: ["x","y","z"]
    })
    

    执行aggregation

    • $unwindorders 数组
    • $lookup 用于 order_id 字段上的集合
    • $unwind 新创建的 orders 包含查找项目的字段
    • $group by _id 并将您的 orders 项目重新组合到一个数组中,而不重复

    聚合查询:

    db.user.aggregate([{
        $unwind: "$orders"
    }, {
        $lookup: {
            from: "order",
            localField: "orders",
            foreignField: "_id",
            as: "orders"
        }
    }, {
        $unwind: "$orders"
    }, {
        $group: {
            _id: "$_id",
            name: {
                $first: "$name"
            },
            orders: {
                $addToSet: "$orders"
            }
        }
    }])
    

    这会给你:

    {
        "_id": ObjectId("5798a8e1968539bb0a98d1c3"),
        "name": "fred",
        "orders": [{
            "_id": ObjectId("578d706916f07969c4b0cad3"),
            "date": ISODate("2012-12-19T06:01:17.171Z"),
            "items": ["x", "y", "z"]
        }, {
            "_id": ObjectId("578d706916f07969c4b0cad2"),
            "date": ISODate("2012-12-20T06:01:17.171Z"),
            "items": ["a", "b", "c", "d"]
        }]
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-11
      • 1970-01-01
      • 2016-09-22
      • 2014-07-30
      • 2016-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多