Как я могу рекомбинировать ненужные документы? - PullRequest
1 голос
/ 10 марта 2020

У меня есть следующий документ:

{
    "_id" : ObjectId("5881cfa62189aa40268b458a"),
    "description" : "Document A",
    "companies" : [ 
        {"code" : "0001"}, 
        {"code" : "0002"}, 
        {"code" : "0003"}
    ]
}

Я хочу отфильтровать массив companies, чтобы удалить некоторые объекты на основе поля code.

Я пытался используйте раскрутку, а затем сопоставление, чтобы отфильтровать компании, но я не знаю, как объединить объекты. Есть ли другой способ сделать это?

Вот что я пробовал до сих пор:

db.getCollection('test').aggregate([
    {
        $unwind: {
            'path': '$companies'
        }
    },
    {
        $match: {
            'companies.code': {$in: ['0001', '0003']}
        }
    }
    // How do I merge them back into a single document?
]);

Ответы [ 3 ]

1 голос
/ 10 марта 2020

Лучшим способом было бы просто использовать оператор $ filter в массиве.

db.getCollection('test').aggregate([
    {
     $project: 
       {
         companies: {
             $filter: { 
                  input: '$companies', 
                  as: 'company', 
                  cond: {$in: ['$$company.code', ['0001', '0003']]}
             } 
         }
       }
    }
])
1 голос
/ 10 марта 2020

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

db.getCollection('testcol').aggregate([     
    {$unwind: {'path': '$companies'}},
    {$match: {'companies.code': {$in: ['0001', '0003']}}},     
    {$group: {_id: "$_id", description: { "$first": "$description" } , "companies": { $push: "$companies" }}} ,

])
1 голос
/ 10 марта 2020

Вы можете $ group и управлять структурой документа таким образом, но это утомительная работа, так как вам нужно указать каждое поле, которое вы хотите сохранить.

Я рекомендую вместо того, чтобы разматывать используйте $ filter для соответствия таким компаниям:

db.getCollection('test').aggregate([
    {
        $addFields: {
            companies: {
                $filter: {
                    input: "$companies",
                    as: "company",
                    cond: {$in: ["$$company.code", ['0001', '0003']]}
                }
            }
        }
    },
    {  // we now need this match as documents with no matched companies might exist
        $match: {
            "companies.0": {$exists: true}
        }
    }
])
...