раскрутить и сгруппировать объекты вложенного массива в mongodb - PullRequest
0 голосов
/ 25 мая 2018

В mongodb у меня есть такая структура данных:

{
    "data" : [ 
        {
            "car" : [ 
                {
                    "model" : "aaa",
                }, 
                {
                    "model" : "bbb",
                }, 
                {
                    "model" : "ccc",
                }
            ],
            "user" : {
                "id" : "123"
            }
        }
    ],
}

И я хочу сгруппировать и посчитать поле модели автомобиля.Итак, сначала я попробовал метод раскрутки следующим образом:

.aggregate([
  { $project: {"data.car.model":1, "data.user.id":1} },
  { $unwind: {
      path: "$data.car",
      preserveNullAndEmptyArrays: true
      } },
  { $group: {
      _id: "$data.car.model",
      count: { $sum: 1 }
      } }
])

Но результат:

{
    "_id" : [ ["aaa", "bbb", "ccc"] ],
    "count" : 1.0
}

, чего я не хотел, так как модель не раскручивалась.Я надеюсь, что получу результат:

[{_id:"aaa",count:1}, {_id:"bbb",count:1}, {_id:"ccc", count:1}]

Затем, просмотрев массив раскрутки mongodb, вложенный в массив документов , я попробовал $ project для вложенного массива:

.aggregate([
  { $project: {"car":"$data.car.model", "user":"$data.user.id"} },
])

Но результат таков:

{
    "car" : [ ["aaa", "bbb", "ccc"] ],
    "user" : ["123"]
}

Как видите, машина и пользователь были встроены в массив, который я до сих пор не могу применить метод $ unwind.Тем не менее, я надеюсь, что это будет выглядеть так:

{
    "car" : ["aaa", "bbb", "ccc"],
    "user" : "123"
}

Монго, которое я использую, - 3.2, я много искал в Интернете, но не нашел ответа.Есть ли возможность сделать это?

1 Ответ

0 голосов
/ 25 мая 2018

Вам необходимо $unwind "каждый" массив независимо:

.aggregate([
  { "$unwind": { "path": "$data", "preserveNullAndEmptyArrays": true } },
  { "$unwind": { "path": "$data.car", "preserveNullAndEmptyArrays": true } },
  { "$group": {
    "_id": "$data.car.model",
    "count": { "$sum": 1 }
  }}
])

Вы не можете "достичь" и $unwind как вы пытались.Таким образом, вы сначала «распаковываете» внешний массив, а затем «внутренний».Затем документы сливаются для группировки.

Альтернативный подход может заключаться в использовании $reduce для «выравнивания массива» перед «разматыванием»:

.aggregate([
  { "$project": {
    "data": {
      "$reduce": {
        "input": "$data.car",
        "initialValue": [],
        "in": {
          "$concatArrays": [ "$$value", "$$this" ]
        }
      }
    }
  }},
  { "$unwind": "$data" },
  { "$group": {
    "_id": "$data.model",
    "count": { "$sum": 1 }
  }}
])

Но на самом деле это не рекомендуется, поскольку «проекция» более затратна, чем затраты на использование $unwind для каждого уровня вложенности в массиве.

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