MongoDB-对象?为什么我总共需要_id

MongoDB-对象?为什么我总共需要_id,mongodb,aggregation-framework,Mongodb,Aggregation Framework,以下是MongoDB教程中的一个示例(此处为it集合: 如果我将\u id替换为wordTest等其他内容,我将收到错误消息: "errmsg" : "exception: the group aggregate field 'Test' must be defined as an expression inside an object", "code" : 15951, "ok" : 0 谁能帮我理解为什么我的命令中需要\u id?我认为MongoDB会自动分配id,如果使用的话不会提供id

以下是MongoDB教程中的一个示例(此处为it集合:

如果我将
\u id
替换为word
Test
等其他内容,我将收到错误消息:

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

谁能帮我理解为什么我的命令中需要
\u id
?我认为MongoDB会自动分配id,如果使用的话不会提供id。

$group
阶段,
\u id
用于指定组条件。您显然需要它

如果您熟悉SQL世界,可以将其视为
GROUPBY
子句



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

\u id
字段是必需的,但如果您不希望根据相关内容进行聚合,可以将其设置为
null
一个或多个键。不使用它将导致字段上的单个聚合值。因此,它在该上下文中充当“保留字”,指示每个组的结果“标识符”或键是什么

在您的情况下,按
\u id:“$state”
分组将导致
n
聚合
totalPop
的结果,前提是
n
状态有不同的值(类似于从表中按状态分组)。然而

$group : {_id : null, totalPop: { $sum: "$pop" }}}
将为
totalPop
(类似于表中的
SELECT SUM())提供一个结果


此行为在group operator中有很好的描述。

我们将了解
$group
阶段中的
\u id
字段,并查看在组聚合阶段构造
\u id
的一些最佳实践。让我们看看此查询:


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

我们可能不清楚的一件事是,
\u id
字段为什么以这种“文档”方式构造?我们也可以这样做:


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

我们不这样做,因为在这些输出文档中,这个数字的确切含义并不明确。因此,我们实际上不知道。在某些情况下,这意味着在解释这些文档时可能会出现混淆。因此,另一种情况可能是将一个
\u 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()

$push
只是将元素推送到生成数组中。通常,可能需要将提升字段分组到更高级别:


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

将表达式解析为文档作为
\u 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
  }
}])

在SQL中,我有group by和group by$state字段,\u id看起来不像任何SQL模拟。
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
  }
}])