Фильтр и агрегирование вложенных данных mongodb - PullRequest
0 голосов
/ 05 мая 2020
{
    "_id" : ObjectId("5eb1116ed99e7c68395d479c"),
    "sheets" : [
        {
            "Sheet1" : [
                {
                    "headers" : [
                        "name,mobile"
                    ],
                    "data_count" : 10
                }
            ]
        }
    ],

    "name" : "2.csv"
},

{
    "_id" : ObjectId("5eb1116ed99e7c68395d480c"),
    "sheets" : [
        {
            "Sheet1" : [
                {
                    "headers" : [
                        "name,mobile,mobile1,mobile2,email1,email2"
                    ],
                    "data_count" : 30
                }
            ],
                        "Sheet2" : [
                {
                    "headers" : [
                        "name,mobile,mobile1"
                    ],
                    "data_count" : 20
                }
            ]
        }
    ],
    "name" : "1.csv"
}

У меня есть несколько документов в коллекции, поэтому я передам идентификатор и имя листа, например Sheet2, и я хочу получить сумму количества данных для всех входных идентификаторов и листов

, поэтому предположим, что выше если мой ввод - [{file_id: "5eb1116ed99e7c68395d479 c", sheet_name: "Sheet1"}, {file_id: "5eb1116ed99e7c68395d480 c", sheet_name: "Sheet2"}]

, поэтому вывод должен быть data_count это 30

1 Ответ

1 голос
/ 05 мая 2020

Для этого можно использовать конвейер агрегации mongodb. Я не уверен, почему у вас есть поля ваших листов в виде массива, если он содержит только один объект, содержащий все листы. Я бы предложил следующее:

Sample Do c

{
    _id    : ObjectId('5eb1116ed99e7c68395d480c'),
    sheets : [
        {
            name : 'Sheet 1',
            data : {
                headers    : [ 'name,mobile,mobile1,mobile2,email1,email2' ],
                data_count : 30
            }
        },
        {
            name : 'Sheet 2',
            data : {
                headers    : [ 'name,mobile,mobile1' ],
                data_count : 20
            }
        }
    ]
}

Независимо от этого, вы можете получить желаемый результат с помощью имеющейся у вас схемы применяя несколько $match и $unwind к документам, пока вы не получите данные, разделенные на поле _id и поле sheets, содержащее только одно значение. Затем вы можете легко сопоставить нужные документы, используя $match с $or.

Запрос

db.collection.aggregate([
        {
            $match : {
                _id : {
                    $in : [ ObjectId('5eb1116ed99e7c68395d479c'), ObjectId('5eb1116ed99e7c68395d480c') ]
                }
            }
        },
        {
            $unwind : '$sheets'
        },
        {
            $project : {
                _id    : 1,
                sheets : {
                    $objectToArray : '$sheets'
                }
            }
        },
        {
            $unwind : '$sheets'
        },
        {
            $unwind : '$sheets.v'
        },
        {
            $match : {
                $or : [
                    {
                        _id        : ObjectId('5eb1116ed99e7c68395d479c'),
                        'sheets.k' : 'Sheet1'
                    },
                    {
                        _id        : ObjectId('5eb1116ed99e7c68395d480c'),
                        'sheets.k' : 'Sheet2'
                    }
                ]
            }
        },
        {
            $group : {
                _id        : null,
                data_count : {
                    $sum : '$sheets.v.data_count'
                }
            }
        }
    ]);

Тест : Тестовый конвейер агрегации здесь: mongoplayground

Вывод

[
  {
    "_id": null,
    "data_count": 30
  }
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...