子查询替换包含在列表A中的列表中的值,用于集合B mongodb中的键

时间:2017-11-18 10:35:45

标签: mongodb

我有一个mongodb的查询问题

我的数据库中有2个集合,名称为statusmenu

status _id中的主键是menu集合中已购买列表值的外键

status集合:

{
    "_id": "green", "description": "running"
}
{
    "_id": "yellow", "description": "prepareing"
}
{
    "_id": "black", "description": "closing"
}
{
    "_id": "red", "description": "repairing"
}

menu集合:

{
    "name": "tony",
    "bought": [
        {
            "notebook": "green"
        },
        {
            "cellphone": "red"
        }
    ]
}
{
    "name": "andy",
    "bought": [
        {
            "fan": "black"
        }
    ]
}

如何查询以获得以下答案?

(只需将description替换为_id

{
    "name": "tony",
    "bought": [
        {
            "notebook": "running"
        },
        {
            "cellphone": "repairing"
        }
    ]
}

NoSQL的子查询问题是什么?如何使用谷歌的关键词?

1 个答案:

答案 0 :(得分:1)

以下是使用聚合的版本:

我们从一个$unwind阶段开始,提取每个在另一行中购买的

然后使用$objectToArray来标准化已购买的字段。

然后我们可以执行$lookup加入状态。

然后我们使用$group按名称重组

$arrayToObject重置为非正规化风格

> db.menu.find()
{ "_id" : ObjectId("5a102b0b49b317e3f8d6268b"), "name" : "tony", "bought" : [ { "notebook" : "green" }, { "cellphone" : "red" } ] }
{ "_id" : ObjectId("5a102b0b49b317e3f8d6268c"), "name" : "andy", "bought" : [ { "fan" : "black" } ] }
> db.status.find()
{ "_id" : "green", "description" : "running" }
{ "_id" : "yellow", "description" : "prepareing" }
{ "_id" : "black", "description" : "closing" }
{ "_id" : "red", "description" : "repairing" }
> db.menu.aggregate([
{$unwind: '$bought'}, 
{$project: {name: 1, bought: {$objectToArray: '$bought'}}}, {$unwind: '$bought'}, 
{$lookup: {from: 'status', localField: 'bought.v', foreignField: '_id', as: "status"}}, 
{$project: {name: 1, bought: ["$bought.k", { $arrayElemAt: ["$status.description", 0]}]}}, 
{$addFields: {b: {v: {$arrayElemAt: ['$bought', 1]}, k: { $arrayElemAt: ['$bought', 0]}}}}, 
{$group: {_id: { name: '$name', _id: "$_id"}, b: {$push: "$b"}}},     
{$project: {_id: "$_id._id", name: "$_id.name", bought: {$arrayToObject: "$b"}}}
])
{ "_id" : ObjectId("5a102b0b49b317e3f8d6268c"), "name" : "andy", "bought" : { "fan" : "closing" } }
{ "_id" : ObjectId("5a102b0b49b317e3f8d6268b"), "name" : "tony", "bought" : { "notebook" : "running", "cellphone" : "repairing" } }

我认为它可以以更简单的方式进行,但我不知道如何(我很乐意知道)。