【问题标题】:Deep linking for 3 levels in MongoDBMongoDB 中 3 个级别的深度链接
【发布时间】:2017-01-09 02:44:01
【问题描述】:

我需要从数据库中检索整个单个对象层次结构作为 JSON。我决定使用带有 $lookup 支持的 MongoDB。

所以我有三个集合:

1.餐厅

{
    "_id" : ObjectId("57c6a02021c8b8d04443aa7c"),
    "name" : "KFC",
    "city" : "Lahore",
    "area" : "Johar town",
    "min_order" : "500",
    "del_time" : "1 hour",
    "del_fees" : "5",
    "pre_order" : "no",
    "rating_star" : "0",
    "rating_no" : 0,
    "status" : "1",
    "working_hours" : {
        "monday" : "2pm 6am",
        "tuesday" : "6am 8pm",
        "wednesday" : "9pm 5pm",
        "thursday" : "3pm 6pm",
        "friday" : "1pm 9pm",
        "saturday" : "4pm 5pm",
        "sunday" : "4pm 8pm"
    },
    "cuisines" : [
        "fast food, pizza"
    ],
    "payments" : [
        "cash,credit card,paypal"
    ]
}

2。类别

"categories" : [
    {
        "_id" : ObjectId("57c6a05421c8b8d04443aa7e"),
        "restaurant_id" : ObjectId("57c6a02021c8b8d04443aa7c"),
        "name" : "Breakfast",
        "category_id" : "1",
        "__v" : 0
    },
    {
        "_id" : ObjectId("57c6a06021c8b8d04443aa7f"),
        "restaurant_id" : ObjectId("57c6a02021c8b8d04443aa7c"),
        "name" : "Special",
        "category_id" : "2",
        "__v" : 0
    }
]

3。项目

"items" : [
            {
                "_id" : ObjectId("57c6da8cc8d053e8310dfe65"),
                "restaurant_id" : ObjectId("57c6a02021c8b8d04443aa7c"),
                "category_id" : ObjectId("57c6a05421c8b8d04443aa7e"),
                "name" : "Water",
                "price" : "55",
                "rating" : "0",
                "__v" : 0
            },
            {
                "_id" : ObjectId("57c6da96c8d053e8310dfe66"),
                "restaurant_id" : ObjectId("57c6a02021c8b8d04443aa7c"),
                "category_id" : ObjectId("57c6a05421c8b8d04443aa7e"),
                "name" : "Milk",
                "price" : "55",
                "rating" : "0",
                "__v" : 0
            }
        ]

我想要这样的 Json 响应输出

{
    "_id" : ObjectId("57c6a02021c8b8d04443aa7c"),
    "name" : "KFC",
    "city" : "Lahore",
    "area" : "Johar town",
    "min_order" : "500",
    "del_time" : "1 hour",
    "del_fees" : "5",
    "pre_order" : "no",
    "rating_star" : "0",
    "rating_no" : 0,
    "status" : "1",
    "working_hours" : {
        "monday" : "2pm 6am",
        "tuesday" : "6am 8pm",
        "wednesday" : "9pm 5pm",
        "thursday" : "3pm 6pm",
        "friday" : "1pm 9pm",
        "saturday" : "4pm 5pm",
        "sunday" : "4pm 8pm"
    },
    "cuisines" : [
        "fast food, pizza"
    ],
    "payments" : [
        "cash,credit card,paypal"
    ],
    "__v" : 0,
    "categories" : [{
        "_id" : ObjectId("57c6a05421c8b8d04443aa7e"),
        "restaurant_id" : ObjectId("57c6a02021c8b8d04443aa7c"),
        "name" : "Breakfast",
        "category_id" : "1",
        "__v" : 0,
        "items" : [
            {
                "_id" : ObjectId("57c6da8cc8d053e8310dfe65"),
                "restaurant_id" : ObjectId("57c6a02021c8b8d04443aa7c"),
                "category_id" : ObjectId("57c6a05421c8b8d04443aa7e"),
                "name" : "Water",
                "price" : "55",
                "rating" : "0",
                "__v" : 0
            },
            {
                "_id" : ObjectId("57c6da96c8d053e8310dfe66"),
                "restaurant_id" : ObjectId("57c6a02021c8b8d04443aa7c"),
                "category_id" : ObjectId("57c6a05421c8b8d04443aa7e"),
                "name" : "Milk",
                "price" : "55",
                "rating" : "0",
                "__v" : 0
            }
        ]
    }]
}

我还是这样的

db.restaurants.aggregate([{
    $lookup: {
        from: "categories",
        localField: "_id",
        foreignField: "restaurant_id",
        as: "categories"
    }
}])

Restaurants 和 categories 工作正常,但我如何处理 categories 中的每个类别项目?

【问题讨论】:

    标签: node.js mongodb mongoose mongodb-query aggregation-framework


    【解决方案1】:

    您可以尝试以下聚合管道,记住您需要对创建的查找数组执行 $unwind 操作,以便下一个 $lookup 要应用的操作:

    db.restaurants.aggregate([
        {
            "$lookup": {
                "from": "categories",
                "localField": "_id",
                "foreignField": "restaurant_id",
                "as": "categories"
            }
        },
        { "$unwind": "$categories" },
        {
            "$lookup": {
                "from": "items",
                "localField": "categories._id",
                "foreignField": "category_id",
                "as": "categories.items"
            }
        }
     ])
    

    【讨论】:

    • 我也这样做了,但现在这是一家餐厅,所有类别都有不同的对象,包括餐厅和其他细节,但我想要一个。
    【解决方案2】:

    我不认为这是直接可能的。根据documentation on $lookup:

    如果你的 localField 是一个数组并且你想匹配元素 在它里面反对一个单一元素的foreignField,你会 需要 $unwind 数组作为聚合管道的一个阶段。

    所以,基本上您需要 $unwind 您的类别数组才能查找项目。但是,只要将它重新拼凑起来,您就可以发挥创造力。

    例如,这接近你想要的:

    db.restaurants.aggregate([
    {
        $lookup: {
            from: "categories",
            localField: "_id",
            foreignField: "restaurant_id",
            as: "categories"
        }
    },
    {
        $unwind: "$categories"
    },
    {
        $lookup: {
            from: "items",
            localField: "categories._id",
            foreignField: "category_id",
            as: "items"
        }
    },
    {
        $project:{
            category: {
                elem: "$categories",
                items: "$items"
            }
        }
    },
    {
        $group: {
            _id: "$_id",
            categories: {$addToSet: "$category"}
        }
    },
    {
        $lookup: {
            from: "restaurants",
            localField: "_id",
            foreignField: "_id",
            as: "restaurant"
        }
    },
    {
        $unwind: "$restaurant"
    },
    {
        $project: {
            _id:false,
            restaurant_id:"$_id",
            categories:true,
            restaurant_data:"$restaurant"
        }
    }
    ]);
    

    【讨论】:

    • 它没有显示我上面在问题中提到的结果。无论如何谢谢你醒来的回应
    • 对,这个答案并不意味着产生确切的结果。但它应该为您提供具有相同层次结构的所有相同数据:餐厅 -> 类别 -> 项目
    • 是的,它就是这样显示的。这真好。但你能告诉我如何删除 _id object() 餐厅重命名它就像那个 restaurant_id
    • 如果我明白你的意思,请检查我添加到末尾的附加 $project 阶段。
    • 是的,就像我想要的那样,但在餐厅数据中我有 "_id" : ObjectId("57c6a03621c8b8d04443aa7d") 我想删除它以及我在类别或项目中拥有的所有其他数据。我怎么能做到。唤醒您的查询对我很有帮助,非常感谢它也解决了我的这个问题
    猜你喜欢
    • 2010-12-06
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 2014-01-23
    相关资源
    最近更新 更多