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

$ 设立 (聚合阶段)

注意

消歧

以下页面讨论聚合阶段 $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 操作中指定现有字段名会导致替换原始字段。

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

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

可以用一个字段替换另一个字段。在以下示例中,title 字段替换了 _id 字段。

以下聚合操作使用 $set 将每份文档的 _id 字段替换为 title 字段的值,并将 title 字段替换为 string "movie":

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

您可以使用 $set 和 $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 指南。