MongoDB:将集合合并到单个文档中



我正在查找有关联接及其在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)中转换为单个文档,但从编写查询的方式来看,是否有可能返回预先格式化的文档?

您可以执行单个aggregation来获得该结果。mongo$lookup文档的一部分展示了如何使用数组进行查找。

给定以下集合:

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

  • orders阵列的$unwind
  • _id字段上order集合的$lookup
  • $unwind新建orders字段,包含已查找的项目
  • $group乘以_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"]
    }]
}

相关内容

  • 没有找到相关文章

最新更新