Запросите несколько свойств одновременно, получая общее среднее и массив - PullRequest
0 голосов
/ 08 января 2019

Учитывая следующие данные, я пытаюсь получить среднее значение всех их возрастов, в то же время я хочу вернуть массив их имен. В идеале я хочу сделать это всего за один запрос, но, похоже, не могу понять это.

Данные:

users:[
 {user:{
  id: 1,
  name: “Bob”,
  age: 23
 }},
 {user:{
  id: 1,
  name: “Susan”,
  age: 32
 }},
 {user:{
  id: 2,
  name: “Jeff”,
  age: 45
 }
}]

Запрос:

var dbmatch =  db.users.aggregate([
  {$match: {"id" : 1}},
  {$group: {_id: null, avg_age: { $avg: "$age" }}},
  {$group: {_id : { name: "$name"}}}
)]

Запуск вышеуказанных групп по одной выводит ожидаемые результаты: либо _id с нулевым значением, в среднем 27,5, либо массив имен.

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

Код сгенерированного выпуска:

[ { _id: {name: null } } ]

Ожидаемый сгенерированный код:

[
  {name:"Bob"},
  {name:"Susan"},
   avg_age: 27.5
]

Любая помощь будет принята с благодарностью!

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Не уверен, что это именно то, что вы хотите, но этот запрос

db.users.aggregate([
    {
        $match: {
            id: 1
        }
    },
    {
        $group: {
            _id: "$id",
            avg_age: {
                $avg: "$age"
            },
            names: {
                $push: {
                    name: "$name"
                }
            }
        }
    },
    {
        $project: {
            _id: 0
        }
    }
])

Результаты, полученные в результате:

[
  {
    "avg_age": 27.5,
    "names": [
      {
        "name": "Bob"
      },
      {
        "name": "Susan"
      }
    ]
  }
]

Это будет дублировать имена, поэтому, если есть два документа с именем Боб, он будет два раза в массиве. Если вы не хотите дублировать, измените $push на $addToSet.

Кроме того, если вы хотите, чтобы имена были просто массивом имен вместо объектов, измените запрос имен на

  names: {
    $push: "$name"
  }

Это приведет к

[
  {
    "avg_age": 27.5,
    "names": ["Bob", "Susan"]
  }
]

Надеюсь, это поможет,

Томас:)

0 голосов
/ 08 января 2019

Вы можете использовать $facet aggregation для одновременного выполнения нескольких запросов

db.collection.aggregate([
  { "$facet": {
    "firstQuery": [
      { "$match": { "id": 1 }},
      { "$group": {
        "_id": null,
        "avg_age": { "$avg": "$age" }
      }}
    ],
    "secondQuery": [
      { "$match": { "id": 1 }},
      { "$group": { "_id": "$name" }}
    ]
  }}
])
...