агрегация mongodb: если значения двух полей совпадают, добавьте значение другого файла соответствующего словаря в новое поле

#mongodb #aggregation-framework

#mongodb #агрегация-фреймворк

Вопрос:

После использования поиска агрегации среди трех коллекций у меня есть следующий результат.

 [{
_id : "henten",
location: "some place",
devices: [
    {"d_id": 'd0001',
     "z_id": 'z2001'},
    {"d_id": 'd0002',
     "z_id": 'z2002'}
],
store: [
    {"z_name" : 'vera',
     "z_id" : 'z2001'},
    {"z_name" : 'ghora',
     "z_id" : 'z2002'}
]
}]
 

Мне нужно поместить значение ‘d_id’ в словари ‘store’ в виде массива в новое поле с именем ‘DID’, если devices.z_id совпадает с store.z_id.

Я попробовал следующее:

 {
        $addFields: {
            "store.DID" :
            {$filter: {
                input: "$devices.d_id",
                as: 'did',
                cond: {$eq: ['$devices.z_id', '$store.z_id']}
                }}
}}
 

Я также пробовал $redact и $arrayElemAt, которые дают мне такие же неправильные результаты, как следующие:

 [{
_id : "henten",
location: "some place",
devices: [
    {"d_id": 'd0001',
     "z_id": 'z2001'},
    {"d_id": 'd0002',
     "z_id": 'z2002'}
],
store: [
    {"z_name" : 'vera',
     "z_id" : 'z2001',
     "DID" : ['d0001', 'd0002']},
    {"z_name" : 'ghora',
     "z_id" : 'z2002',
     "DID" : ['d0001', 'd0002']}
]
}]
 

В то время как правильный ответ должен быть:

 [{
_id : "henten",
location: "some place",
devices: [
    {"d_id": 'd0001',
     "z_id": 'z2001'},
    {"d_id": 'd0002',
     "z_id": 'z2002'}
],
store: [
    {"z_name" : 'vera',
     "z_id" : 'z2001',
     "DID" : ['d0001']},
    {"z_name" : 'ghora',
     "z_id" : 'z2002',
     "DID" : ['d0002']}
]
}]
 

Как мне подойти к этому? Один z_id может иметь два разных d_id и, следовательно, должен иметь эти два d_id внутри массива DID.

Ответ №1:

Вы можете запустить комбинацию $ map и $ filter, попробуйте:

 db.col.aggregate([
    {
        $addFields: {
            store: {
                $map: {
                    input: "$store",
                    as: "s",
                    in: {
                        z_name: "$s.z_name",
                        z_id: "$s.z_id",
                        DID: {
                            $map: {
                                input: { 
                                    $filter: {
                                        input: "$devices",
                                        as: "d",
                                        cond: { $eq: [ "$d.z_id", "$s.z_id" ] }
                                    }
                                },
                                as: "filtered",
                                in: "$filtered.d_id"
                            }
                        }
                    }
                }
            }
        }
    }
])
 

Игровая площадка Mongo