MongoDB - 对象?为什么我需要聚合_id

use*_*890 10 mongodb aggregation-framework

以下是MongoDB教程中的一个示例(此处为收集邮政编码db:

db.zipcodes.aggregate( [
   { $group: { _id: "$state", totalPop: { $sum: "$pop" } } },
   { $match: { totalPop: { $gte: 10*1000*1000 } } }
] )
Run Code Online (Sandbox Code Playgroud)

如果我_id用其他类似的东西替换Test,我会得到错误信息:

"errmsg" : "exception: the group aggregate field 'Test' must be defined as an expression inside an object",
"code" : 15951,
"ok" : 0
Run Code Online (Sandbox Code Playgroud)

有人能帮我理解为什么_id我的命令需要吗?我认为MongoDB会自动分配ID,如果使用不提供ID.

0_0*_*0_0 7

_id字段是强制性的,但null如果您希望针对一个或多个键进行聚合,则可以将其设置为。不使用它会导致字段上的单个聚合值。因此,它在此上下文中充当“保留词”,指示每个组的结果“标识符”/键是什么。

在您的情况下,分组依据_id: "$state"将导致 的n汇总结果totalPop,前提是(类似于)有n不同的值。然而,stateSELECT SUM() FROM table GROUP BY state

$group : {_id : null, totalPop: { $sum: "$pop" }}}
Run Code Online (Sandbox Code Playgroud)

将为totalPop(类似于SELECT SUM() FROM table)提供单一结果。

这种行为在组操作员文档中有很好的描述。


Syl*_*oux 6

在一个$group阶段,_id用于指定组条件.你显然需要它.

如果您熟悉SQL世界,请将其视为GROUP BY子句.


请注意,在该上下文中,_id实际上是生成的集合中的唯一标识符,因为根据定义$group,不能生成具有该字段的相同值的两个文档.

  • 在 SQL 中,我有 group by 并且我有按 $state 分组的字段,_id 看起来不像任何 SQL 模拟。 (2认同)

xam*_*mir 5

我们将了解阶段_id内的领域$group并查看_id在组聚合阶段构建s的一些最佳实践.我们来看看这个查询:


db.companies.aggregate([{
  $match: {
    founded_year: {
      $gte: 2010
    }
  }
}, {
  $group: {
    _id: {
      founded_year: "$founded_year"
    },
    companies: {
      $push: "$name"
    }
  }
}, {
  $sort: {
    "_id.founded_year": 1
  }
}]).pretty()
Run Code Online (Sandbox Code Playgroud)

具有文档方法的MongoDB $组

我们可能不清楚的一件事是,为什么该_id领域是以这种"文件"的方式构建的?我们也可以这样做:


db.companies.aggregate([{
  $match: {
    founded_year: {
      $gte: 2010
    }
  }
}, {
  $group: {
    _id: "$founded_year",
    companies: {
      $push: "$name"
    }
  }
}, {
  $sort: {
    "_id": 1
  }
}]).pretty()
Run Code Online (Sandbox Code Playgroud)

没有文档方法的MongoDB $组

我们不是这样做的,因为在这些输出文档中 - 这个数字究竟意味着什么并不明确.所以,我们实际上不知道.在某些情况下,这意味着在解释这些文件时可能会有困惑.因此,另一种情况可能是将_id文档分组为多个字段:


db.companies.aggregate([{
  $match: {
    founded_year: {
      $gte: 2010
    }
  }
}, {
  $group: {
    _id: {
      founded_year: "$founded_year",
      category_code: "$category_code"
    },
    companies: {
      $push: "$name"
    }
  }
}, {
  $sort: {
    "_id.founded_year": 1
  }
}]).pretty()
Run Code Online (Sandbox Code Playgroud)

在MongoDB中将包含多个字段的_id文档分组

$push只需将元素推送到生成数组即可.通常,可能需要将升级字段分组到较高级别:


db.companies.aggregate([{
  $group: {
    _id: {
      ipo_year: "$ipo.pub_year"
    },
    companies: {
      $push: "$name"
    }
  }
}, {
  $sort: {
    "_id.ipo_year": 1
  }
}]).pretty()
Run Code Online (Sandbox Code Playgroud)

在MongoDB中将升级字段分组到上一级

将表达式解析为文档作为_id键是完美的.

db.companies.aggregate([{
  $match: {
    "relationships.person": {
      $ne: null
    }
  }
}, {
  $project: {
    relationships: 1,
    _id: 0
  }
}, {
  $unwind: "$relationships"
}, {
  $group: {
    _id: "$relationships.person",
    count: {
      $sum: 1
    }
  }
}, {
  $sort: {
    count: -1
  }
}])
Run Code Online (Sandbox Code Playgroud)

在MongoDB中将表达式解析为文档作为_id键也是完美的