对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

$ 设立 (聚合阶段)

注意

消歧

以下页面是指聚合阶段 $set。有关更新操作符$set,请参阅$set。

$set

向文档添加新字段。 $set 输出包含输入文档中所有现有字段和新字段的文档。

$set 阶段是 $addFields 的别名。

这两个阶段都等同于 $project 阶段,该阶段明确指定输入文档中的所有现有字段并添加新字段。

可以使用 $set 查找托管在以下环境中的部署:

  • MongoDB Atlas :用于在云中部署MongoDB 的完全托管服务

$set 采用以下形式:

{ $set: { <newField>: <expression>, ... } }

指定要添加的每个字段的名称,并将其值设置为聚合表达式或空对象。

重要

如果新字段名称与现有字段名称(包括 _id)匹配,$set 将使用指定的表达式覆盖该字段的值。

  • $set 将新字段附加到现有文档。可以在聚合操作中包含一个或多个 $set 阶段。

  • 您可以将 $set 与嵌入式对象一起使用。您可以将值设立为聚合表达式或空对象。示例,接受以下嵌套对象:

    {$set: { a: { b: { } } } }

    要将字段添加到嵌入式文档(包括数组中的文档),请使用点表示法。请参阅示例。

  • 要使用 $set 向现有大量字段添加元素,请使用 $concatArrays。请参阅示例。

本页上的示例使用 sample_mflix 数据集中的数据。有关如何将此数据集加载到自管理MongoDB 部署中的详细信息,请参阅加载样本数据集。如果对示例数据库进行了任何修改,则可能需要删除并重新创建数据库才能运行本页上的示例。

以下操作使用两个 $set 阶段在输出文档中包含三个新字段:

db.movies.aggregate( [
{ $match: { runtime: { $gt: 1000 } } },
{
$set: {
imdbScoreScaled: { $multiply: [ "$imdb.rating", 10 ] },
runtimeHours: {
$floor: { $divide: [ "$runtime", 60 ] }
}
}
},
{
$set: {
totalScore: {
$add: [ "$imdbScoreScaled", "$runtimeHours" ]
}
}
}
] )
[
{ _id: ..., title: 'Baseball', runtime: 1140, imdbScoreScaled: 91, runtimeHours: 19, totalScore: 110 },
{ _id: ..., title: 'Centennial', runtime: 1256, imdbScoreScaled: 85, runtimeHours: 20, totalScore: 105 }
]
...
第一阶段 ($set):
第一个 $set 阶段添加两个字段:imdbScoreScaled(将 IMDB 评分乘以 10)和 runtimeHours(将运行时间除以 60 并向下舍入到最接近的整数)。
第二阶段($set):
第二个 $set 阶段添加 totalScore,即上一阶段计算的 imdbScoreScaled 和 runtimeHours 的总和。

使用点符号为嵌入式文档添加新字段。

以下聚合操作将新字段 normalizedRating 添加到嵌入式文档 imdb:

db.movies.aggregate( [
{ $match: { runtime: { $gt: 1000 } } },
{
$set: {
"imdb.normalizedRating": {
$multiply: [ "$imdb.rating", 10 ]
}
}
}
] )
[
{ _id: ..., title: 'Baseball', imdb: { '...': '...', normalizedRating: 91 } },
{ _id: ..., title: 'Centennial', imdb: { '...': '...', normalizedRating: 85 } }
]
...

以下 $set 操作会覆盖 rated字段:

db.movies.aggregate( [
{ $match: { title: "Baseball" } },
{ $set: { rated: "UNRATED" } }
] )
[
{ _id: ..., title: 'Baseball', rated: 'UNRATED' }
]
...

您可以用一个字段替换另一个字段。以下操作将 _id 替换为 title字段值,然后将 title 设置为字符串 "movie":

db.movies.aggregate( [
{ $match: { runtime: { $gt: 1000 } } },
{ $set: { _id: "$title", title: "movie" } }
] )
[
{ _id: 'Baseball', title: 'movie' },
{ _id: 'Centennial', title: 'movie' }
]
...

要向现有大量字段添加元素,请使用 $concatArrays 和 $set。以下操作将 genres字段替换为将当前 genres大量与 [ "Classic" ] 连接起来的新大量:

db.movies.aggregate( [
{ $match: { title: "Baseball" } },
{
$set: {
genres: {
$concatArrays: [ "$genres", [ "Classic" ] ]
}
}
}
] )
[
{ _id: ..., title: 'Baseball', genres: [ 'Documentary', 'History', 'Sport', 'Classic' ] }
]
...

以下聚合操作会向每个文档添加一个新字段 titleWithYear,该字段将电影名称与其发行年份进行连接:

db.movies.aggregate( [
{ $match: { runtime: { $gt: 1000 } } },
{
$set: {
titleWithYear: {
$concat: [
"$title",
" (",
{ $toString: "$year" },
")"
]
}
}
}
] )
[
{ _id: ..., title: 'Baseball', titleWithYear: 'Baseball (1994)' },
{ _id: ..., title: 'Centennial', titleWithYear: 'Centennial (1978)' }
]
...

有关相关阶段,请参阅 $addFields。