MongoDB:将集合加入单个文档

时间:2016-07-27 11:27:13

标签: mongodb nosql

我正在寻找有关联接的一些信息以及它们在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但是,从编写查询的方式来看,是否可以返回预先格式化的文档?

1 个答案:

答案 0 :(得分: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

    您的$unwind数组的
  • orders
  • $lookuporder字段
  • 上收集_id
  • $unwind新创建的orders字段,其中包含已查找的项目
  • {li> $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"]
    }]
}