Поместить объект на корневой уровень в mongoDb - PullRequest
0 голосов
/ 29 октября 2018

У меня есть совокупный запрос, который выбирает результат из 3 коллекций.

Я использую mongoDb 3.4

Один образец документа из результата.

{ 
    "_id" : ObjectId("5ba1717ee4b00ce08ca47cfa"),  
    "name" : "captain jack", 
    "email" : "jack@gmail.com", 
    "mobile" : "9000000023", 
    "status" : "verified", 
    "courses" : [
        {
            "_id" : "13", 
            "name" : "Course (03)"
        },{
            "_id" : "12", 
            "name" : "Course (03)"
        }
    ], 
    "examCompleted" : false, 
    "login" : "5ba1717ee4b00fe08ca47cfa", 
    "partnerMetaInfo" : {
        "_id" : ObjectId("5ba1717ee4b00fe08ca47cfa"), 
        "costCode" : "5761", 
        "hub" : "CALCUTTA", 
        "location" : "Kolkata" 

    }
}

Я пытаюсь вывести partnerMetaInfo на корневой уровень. Также я не могу отфильтровать курсы

Это мой сводный запрос:

db.getCollection("mainCollection").aggregate([
        {
            //Join two collection
            $lookup:{
                from: "Details",
                localField: "username",
                foreignField: "login",
                as: "partnerData"
            }
        },{
            //Limit fields
            $project:{
                "email":1,
                "name":1,
                "mobile":1,
                "status" : 1,
                "courses":"$partnerData.courses",
                "examScore" : "$partnerData.examScore",
                "examCompleted" : "$partnerData.examCompleted",
                "login":"$partnerData.login"
            }
        },
        {
            //Join third collection
            $lookup:{
                from: "PartnerMetaInfo",
                localField: "login",
                foreignField: "partnerId",
                as: "partnerMetaInfo"
            }
        },
        //Remove from partnerData array and place at root level.
        {
            $unwind:
            {
                path: '$courses',
                preserveNullAndEmptyArrays: true
            }
        },{
            $unwind:
            {
                path: '$examScore',
                preserveNullAndEmptyArrays: true
            }
        },{
            $unwind:
            {
                path: '$examCompleted',
                preserveNullAndEmptyArrays: true
            }
        },{
            $unwind:
            {
                path: '$login',
                preserveNullAndEmptyArrays: true
            }
        },//Bring $partnerMetaInfo array to root level.
        {
            $unwind:
            {
                path: '$partnerMetaInfo',
                preserveNullAndEmptyArrays: true
            }
        },{
            $limit:10
        }
    ];

partnerMetaInfo после $ unwind становится объектом. Я хочу сгладить это и привести это на уровне корня.

Может ли какое-нибудь тело помочь мне с этим?

1 Ответ

0 голосов
/ 29 октября 2018

Если все, что вы хотите получить в результате, это содержимое вашего поля partnerMetaInfo, то вы можете просто добавить $ replaceRoot в конце вашего конвейера, например:

{
    $replaceRoot: { "newRoot": { $ifNull: [ "$partnerMetaInfo", {} ] } }
}

В противном случае, если вы хотите просто переместить поля внутри поля partnerMetaInfo в корень, вы должны использовать $ addFields :

{
    $addFields: {
        "partnerMetaInfoId" : "$partnerMetaInfo._id", 
        "costCode" : "$partnerMetaInfo.costCode", 
        "hub" : "$partnerMetaInfo.hub", 
        "location" : "$partnerMetaInfo.location" 
    }
}

Если у вас динамическое количество полей или вы не хотите жестко кодировать имена полей, вы можете использовать следующую логику:

{
    $replaceRoot: { // merge fields of and move them all the way up
        "newRoot": { $mergeObjects: [ "$$ROOT", "$partnerMetaInfo" ] }
    }
}, {
    $project: { // remove the "partnerMetaInfo" field
        "partnerMetaInfo": 0
    }
}
...