蒙古数据库 - 对象?为什么聚合操作需要_id?

15

这里有一个来自MongoDB教程的例子(它使用的集合可在ZIP Code db中找到):

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

如果我将_id替换为其他内容,比如单词Test,那么我会收到错误信息:

如果我将_id替换成其他的东西,例如单词Test,那么我会得到一个错误消息:

"errmsg" : "exception: the group aggregate field 'Test' must be defined as an expression inside an object",
"code" : 15951,
"ok" : 0

有谁能帮我理解为什么我的命令需要 _id?我以为如果没提供,MongoDB 会自动分配ID。

3个回答

9

_id字段是必填项,但如果您不希望按键或键聚合,则可以将其设置为null。不使用它会导致对字段进行单个聚合值。因此,在这种情况下,它充当“保留字”,指示每个组的结果“标识符”/键。

在您的情况下,按_id: "$state"分组将导致n个聚合结果totalPop,前提是staten个不同的值(类似于SELECT SUM() FROM table GROUP BY state)。而

$group : {_id : null, totalPop: { $sum: "$pop" }}}

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

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


8
$group阶段中,_id用于指定分组条件。显然,你需要它。
如果你熟悉SQL世界,可以将其视为GROUP BY子句。
请注意,在这种情况下,_id实际上是生成的集合中的唯一标识符,因为按定义,$group不能产生具有该字段相同值的两个文档。

4
在SQL中,我有一个“group by”语句,而我要用$state字段进行分组,但是_id字段似乎没有任何SQL相似之处。 - user1700890

6
我们将了解$group阶段中的_id字段,并查看一些构建聚合阶段中_id的最佳实践。让我们来看一下这个查询:

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

MongoDB使用文档方法进行$group

有一件事可能不太清楚,为什么_id字段是这样构建的“文档”方式?我们也可以这样做:


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

We do not use this approach for MongoDB $group because the output documents do not explicitly state the meaning of the numbers. This lack of clarity can lead to confusion when interpreting the documents. Instead, we can group an _id document with multiple fields.

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()

在MongoDB中使用$group对具有多个字段的_id文档进行分组

$push会将元素推入生成数组中。通常,可能需要在提升字段到上一层级后进行分组:


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

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

It's also perfect to have an expression that resolves to a document as a _id key in MongoDB


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接