$ сумма значений в массиве в mongodb

У нас есть коллекция Mongo, которая имеет эту форму:

[
    {
        "_id" : "34210db0-6g91-83e8-ae8c-659f064f503f",
        "dateReceived" : ISODate("2018-01-01T00:00:00.000Z"),
        "group" : null,
        "clientShortName" : "My Client Name",
        "sourceShortName" : "Datasource Name",
        "files" : [ 
            {
                "_id" : "807061f0-2d77-87e8-8610-9ff3cbc9c774"
                "status" : 1,
                "fileName" : "filename1.csv",
                "numRows" : 15,

            }, 
            {
                "_id" : "587036f0-2n65-55e8-8610-3ee3cbc9c814"
                "status" : 8,
                "fileName" : "filename2.csv",
                "numRows" : 30,
            }
        ]
    }
]

У нас есть запрос Монго, использующий "find" в сочетании с "map" для получения преобразованного вывода. Команда find/map выглядит так:

db.getCollection('batches')
.find({_id: "34210db0-6g91-83e8-ae8c-659f064f503f"}, {"__v": false, "files.diffHistory": false})
.map( doc =>
    {
        doc.id = doc._id;
        doc.clientName = doc.clientShortName;
        doc.dataSourceName = doc.sourceShortName;
        delete doc._id;
        delete doc.clientShortName;
        delete doc.sourceShortName;

        doc.numFiles = NumberInt(doc.files.length);

        doc.files = doc.files.map( file =>
            {
                file.id = file._id;
                delete file._id;
                delete file.__v;
                delete file.edits;

                return file;
            }
        );

        // broken....how should this be formatted?    
        doc.totalNumRows = {$sum: doc.files.numRows};

        return doc;
    }
)

Эта команда find/map работает и выдает ожидаемый вывод, КРОМЕ суммирования totalNumRows. То, что мы пытаемся сделать, это сложить все поля "files.numRows", чтобы мы получили единую сводную запись на верхнем уровне возвращаемого набора данных. Т.е. мы бы увидели набор результатов, который выглядит так:

[
        {
            "id" : "34210db0-6g91-83e8-ae8c-659f064f503f",
            "dateReceived" : ISODate("2018-01-01T00:00:00.000Z"),
            "group" : null,
            "clientName" : "My Client Name",
            "dataSourceName" : "Datasource Name",
            "files" : [ 
                {
                    "id" : "807061f0-2d77-87e8-8610-9ff3cbc9c774"
                    "status" : 1,
                    "fileName" : "filename1.csv",
                    "numRows" : 15,

                }, 
                {
                    "id" : "587036f0-2n65-55e8-8610-3ee3cbc9c814"
                    "status" : 8,
                    "fileName" : "filename2.csv",
                    "numRows" : 30,
                }
            ],

            "totalNumRows": 45

        }
    ]

Все, что попробовал до сих пор, дает неправильный запрос. Кто-нибудь знает правильную команду / формат для суммирования поля "numRows" нашего подкаталога "file"?

1 ответ

Решение

Ну, вы можете сделать что-то лучше и быстрее, чем это... Попробуйте $projectпереименовать ваше фактическое имя поля, а затем $sum чтобы получить общее количество numRows

db.collection.aggregate([
  { "$match": { _id: "34210db0-6g91-83e8-ae8c-659f064f503f" }},
  { "$project": {
    "totalNumRows": {
      "$sum": "$files.numRows"
    },
    "clientName": "$clientShortName",
    "dataSourceName": "$sourceShortName",
    "files": "$files"
  }}
])

Это даст следующий вывод

[
  {
    "_id": 1111,
    "clientName": "My Client Name",
    "dataSourceName": "Datasource Name",
    "files": [
      {
        "fileName": "filename1.csv",
        "id": 2222,
        "numRows": 15,
        "status": 1
      },
      {
        "fileName": "filename2.csv",
        "id": 3333,
        "numRows": 30,
        "status": 8
      }
    ],
    "totalNumRows": 45
  }
]
Другие вопросы по тегам