Совокупные вложенные массивы - PullRequest
1 голос
/ 16 марта 2019

У меня есть несколько документов, и я пытаюсь объединить все документы с companyId = xxx и вернуть один массив со всеми статусами.

Так это будет выглядеть так:

[
{
    "status": "created",
    "date": "2019-03-16T10:59:59.200Z"
},
{
    "status": "completed",
    "date": "2019-03-16T11:00:37.750Z"
},
{
    "status": "created",
    "date": "2019-03-16T10:59:59.200Z"
},
{
    "status": "completed",
    "date": "2019-03-16T11:00:37.750Z"
},
{
    "status": "created",
    "date": "2019-03-16T10:59:59.200Z"
},
{
    "status": "completed",
    "date": "2019-03-16T11:00:37.750Z"
},
{
    "status": "created",
    "date": "2019-03-16T10:59:59.200Z"
},
{
    "status": "completed",
    "date": "2019-03-16T11:00:37.750Z"
}

]

Документ выглядит так:

[
{
    "companyId": "xxx",
    "position": "",
    "section": "",
    "comment": "",
    "items": [
        {
            "any": "111",
            "name": "some name",
            "description": "some description",
            "version": "3",
            "status": [
                {
                    "status": "created",
                    "date": "2019-03-16T10:59:59.200Z"
                },
                {
                    "status": "completed",
                    "date": "2019-03-16T11:00:37.750Z"
                }
            ]
        },
        {
            "any": "222",
            "name": "some name",
            "description": "some description",
            "version": "3",
            "status": [
                {
                    "status": "created",
                    "date": "2019-03-16T10:59:59.200Z"
                },
                {
                    "status": "completed",
                    "date": "2019-03-16T11:00:37.750Z"
                }
            ]
        }
    ]
},
{
    "companyId": "xxx",
    "position": "",
    "section": "",
    "comment": "",
    "items": [
        {
            "any": "111",
            "name": "some name",
            "description": "some description",
            "version": "3",
            "status": [
                {
                    "status": "created",
                    "date": "2019-03-16T10:59:59.200Z"
                },
                {
                    "status": "completed",
                    "date": "2019-03-16T11:00:37.750Z"
                }
            ]
        },
        {
            "any": "222",
            "name": "some name",
            "description": "some description",
            "version": "3",
            "status": [
                {
                    "status": "created",
                    "date": "2019-03-16T10:59:59.200Z"
                },
                {
                    "status": "completed",
                    "date": "2019-03-16T11:00:37.750Z"
                }
            ]
        }
    ]
}

]

Есть предложения, как это реализовать?

Затем я хочу перебрать массив (в коде) и посчитать, сколько элементов в статусе создано и завершено. может быть, это можно сделать с помощью запроса?

Заранее спасибо

Ответы [ 3 ]

1 голос
/ 16 марта 2019

В дополнение к ответу @mickl вы можете добавить конвейер $project, чтобы получить результат в виде простого списка состояния и количества.

db.collectionName.aggregate([
    {
        $match: { companyId: "xxx" }
    },
    {
        $unwind: "$items"
    },
    {
        $unwind: "$items.status"
    },
    {
        $replaceRoot: {
            newRoot: "$items.status"
        }
    },
    {
        $group: {
            _id: "$status",
            count: { $sum: 1 }
        }
    },
    {
        $project: {
            "status":"$_id", 
            "count":1,
            _id:0
        }
    }
])
0 голосов
/ 18 марта 2019

Если количество документов, для которых вы выполняете вышеуказанный запрос, слишком велико, вам следует избегать использования $ unwind на начальной стадии конвейера агрегации.
Либо вам следует использовать $ project после $ match , чтобы уменьшить выбор полей или вы можете использовать запрос ниже:

db.col.aggregate([
  {
    $match: {
      companyId: "xxx"
    }
  },
  {
    $project: {
      _id: 0,
      data: {
        $reduce: {
          input: "$items.status",
          initialValue: [

          ],
          in: {
            $concatArrays: [
              "$$this",
              "$$value"
            ]
          }
        }
      }
    }
  },
  {
    $unwind: "$data"
  },
  {
    $replaceRoot: {
      newRoot: "$data"
    }
  }
])
0 голосов
/ 16 марта 2019

Вы можете использовать ниже агрегации:

db.col.aggregate([
    {
        $match: { companyId: "xxx" }
    },
    {
        $unwind: "$items"
    },
    {
        $unwind: "$items.status"
    },
    {
        $replaceRoot: {
            newRoot: "$items.status"
        }
    },
    {
        $group: {
            _id: "$status",
            count: { $sum: 1 }
        }
    }
])

Double $ unwind будет возвращать один статус для каждого документа, а затем вы можете использовать $ replaceRoot для продвижения каждого статуса на корневой уровень вашего документа.

Дополнительно вы можете добавить $ group stage для подсчета документов на status.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...