同时查询多个属性,以获得总体平均值和数组

时间:2019-01-08 14:27:46

标签: mongodb express mongodb-query aggregation-framework

鉴于以下数据,我想获取他们所有年龄的平均值,同时我想返回他们的姓名数组。理想情况下,我只想在一个查询中执行此操作,但似乎无法弄清楚。

数据:

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为null且平均值为27.5,或者为名称数组。

当我使用逗号将它们组合在一起时,我得到:

问题生成的代码:

[ { _id: {name: null } } ]

预期的生成代码:

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

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

您可以使用 $facet aggregation一次运行多个查询

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

答案 1 :(得分:1)

不确定这是否正是您想要的,但是此查询

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"
      }
    ]
  }
]

这将重复名称,因此,如果有两个名称为Bob的文档,则在数组中将是两次。如果您不想重复,请将$push更改为$addToSet

此外,如果您希望名称只是名称数组而不是对象,请将名称查询更改为

  names: {
    $push: "$name"
  }

这将导致

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

希望有帮助,

Tomas:)