Работа с ссылками Mongodb внутри массива рядом с другим контентом - PullRequest
0 голосов
/ 11 апреля 2019

Я хочу использовать структуру агрегации mongodb для 3 коллекций, которые должны "объединяться" в одном запросе. Проблема в том, что когда я ссылаюсь на другую коллекцию с $lookup, она удаляет другое содержимое массива, в котором находится ссылка. Вот коллекция, в которой начинается моя агрегация (пользователи):

{
    "_id" : ObjectId("5c9bea89f4fe8c37175ade58"),
    "kundennummer" : "000001",
    "passwort" : "xxx",
    "status" : "1",
    "onlinestatus" : true,
    "kontakt" : {
        "email" : "test@test.net"
    },
    "thing" : [ 
        {
            "thing_id" : 2,
            "onlinestatus" : false,
            "status" : true,
            "site" : [ 
                {
                    "site_id" : 3,
                    "status": true
                }, 
                {
                    "site_id" : 4,
                    "status": true
                }
            ],
            "refs" : [ 
                {
                    "thing_id" : 11,
                    "status" : true
                }, 
                {
                    "thing_id" : 22,
                    "status" : true
                }
            ]
        }
    ]
}

когда я знаю, что значение site должно быть расширено содержимым, заданным в коллекции site, например:

{
    "_id": 11,
    "name": "test"
},
{
    "_id": 22,
    "name": "test2"
}

Я пытался использовать $lookup и status: true исчез.

db.users.aggregate([{
    $lookup:
    {
        from: "sites",
        localField: "things.site.site_id",
        foreignField: "_id",
        as: "things.site"
    }
}])

редактирование: Чего я хочу добиться, так это:

{
    "_id" : ObjectId("5c9bea89f4fe8c37175ade58"),
    "kundennummer" : "000001",
    "passwort" : "xxx",
    "status" : "1",
    "onlinestatus" : true,
    "kontakt" : {
        "email" : "test@test.net"
    },
    "thing" : [ 
        {
            "thing_id" : 2,
            "onlinestatus" : false,
            "status" : true,
            "site" : [ 
                {
                    "site_id" : 11,
                    "status": true,
                    "name": "test"

                }, 
                {
                    "site_id" : 12,
                    "status": true,
                    "name": "test2"
                }
            ],
            "refs" : [ 
                {
                    "thing_id" : 11,
                    "status" : true,
                    "name": "test"
                }, 
                {
                    "thing_id" : 12,
                    "status" : true,
                    "name": "test2"
                }
            ]
        }
    ]
}

1 Ответ

0 голосов
/ 11 апреля 2019

Чтобы использовать $ lookup для встроенного документа в агрегации MongoDB, вам нужно использовать $ unwind.Он выведет документ для каждого элемента, а затем вы можете использовать $ lookup.Вы также получите результаты от sites с помощью запроса ниже:

db.user.aggregate([
{
    $unwind:  "$thing"
},
{
    $unwind:   "$thing.site"      
},
{
    $unwind:   "$thing.refs"      
},
{
    $lookup: {
        from: 'sites',
        let: { 'siteId': '$thing.site.site_id' },
        pipeline: [
             {
                $match: { 
                    $expr: { 
                        $eq: ['$_id', '$$siteId'] 
                    }
                }
            },    
        ],
        as: 'siteObject'
    }
},
{
    $lookup: {
        from: 'things',
        let: { 'thingId': '$thing.refs.thing_id' },
        pipeline: [
             {
                $match: { 
                    $expr: { 
                        $eq: ['$_id', '$$thingId'] 
                    }
                }
            },    
        ],
        as: 'thingObject'
    }
},
{
    $unwind: "$siteObject"
},
{
    $unwind: "$thingObject"
},
{
    $project: {
        "_id" : 1,
        "kundennummer" : 1,
        "passwort" : 1,
        "status" : 1,
        "onlinestatus" : 1,
        "kontakt" : 1,
        "thing": [{
            "thing_id" : "$thing.thing_id",
            "onlinestatus" : "$thing.onlinestatus",
            "status" : "$thing.status",
            "site" : {
                "site_id":"$thing.site.site_id",
                "status":"$thing.site.status",
                "siteName":"$siteObject.siteName",
            }, 
            "refs" : {
                "thing_id":"$thing.refs.thing_id",
                "status":"$thing.refs.status",
                "siteName":"$thingObject.thingName",
            }, 
        }]
    }
},
{
    $unwind: "$thing"
},
{
    $group: {
        _id: { 
            "_id": "$_id",
            "kundennummer": "$kundennummer",
            "passwort": "$passwort",
            "status":"$status",
            "onlinestatus":"$onlinestatus",
            "kontakt":"$kontakt" 
        },
        thing: { $push: { thing_id: "$thing.thing_id", onlinestatus: "$thing.onlinestatus", status: "$thing.status",site:"$thing.site",refs: "$thing.refs" } }
    }
}

])

Это будет выглядеть следующим образом:

{
"_id" : {
    "_id" : ObjectId("5c9bea89f4fe8c37175ade58"),
    "kundennummer" : "000001",
    "passwort" : "xxx",
    "status" : "1",
    "onlinestatus" : true,
    "kontakt" : {
        "email" : "test@test.net"
    }
},
"thing" : [
    {
        "thing_id" : 2,
        "onlinestatus" : false,
        "status" : true,
        "site" : {
            "site_id" : ObjectId("5caf395e512ab5123bb4b0af"),
            "status" : true,
            "siteName" : "Moto"
        },
        "refs" : {
            "thing_id" : ObjectId("5cb042ea512ab5123bb4b0b0"),
            "status" : true,
            "siteName" : "hi"
        }
    },
    {
        "thing_id" : 2,
        "onlinestatus" : false,
        "status" : true,
        "site" : {
            "site_id" : ObjectId("5caf395e512ab5123bb4b0af"),
            "status" : true,
            "siteName" : "Moto"
        },
        "refs" : {
            "thing_id" : ObjectId("5cb042ea512ab5123bb4b0b1"),
            "status" : true,
            "siteName" : "world"
        }
    },
    {
        "thing_id" : 2,
        "onlinestatus" : false,
        "status" : true,
        "site" : {
            "site_id" : ObjectId("5caf395e512ab5123bb4b0ae"),
            "status" : true,
            "siteName" : "hello"
        },
        "refs" : {
            "thing_id" : ObjectId("5cb042ea512ab5123bb4b0b0"),
            "status" : true,
            "siteName" : "hi"
        }
    },
    {
        "thing_id" : 2,
        "onlinestatus" : false,
        "status" : true,
        "site" : {
            "site_id" : ObjectId("5caf395e512ab5123bb4b0ae"),
            "status" : true,
            "siteName" : "hello"
        },
        "refs" : {
            "thing_id" : ObjectId("5cb042ea512ab5123bb4b0b1"),
            "status" : true,
            "siteName" : "world"
        }
    }
]

}

Результат близок к желаемому результату, и я думаю, что вы не должны следовать такой схеме, это усложнит каждый ваш запрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...