定义
$set向文档添加新字段。
$set输出包含输入文档中所有现有字段和新字段的文档。$set阶段是$addFields的别名。这两个阶段都等同于
$project阶段,该阶段明确指定输入文档中的所有现有字段并添加新字段。
兼容性
可以使用 $set 查找托管在以下环境中的部署:
- MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
$set 采用以下形式:
{ $set: { <newField>: <expression>, ... } }
指定要添加的每个字段的名称,并将其值设置为聚合表达式或空对象。
重要
如果新字段名称与现有字段名称(包括 _id)匹配,$set 将使用指定的表达式覆盖该字段的值。
行为
$set将新字段附加到现有文档。可以在聚合操作中包含一个或多个$set阶段。要使用
$set向现有大量字段添加元素,请使用$concatArrays。请参阅示例。
示例
本页上的示例使用sample_mflix示例数据集中的数据。有关如何将此数据集加载到自管理MongoDB 部署中的详细信息,请参阅加载示例数据集。如果对示例数据库进行了任何修改,则可能需要删除并重新创建数据库才能运行本页上的示例。
使用两个$set 阶段
以下操作使用两个 $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)' } ] ...
本页上的C#示例使用Atlas示例数据集中的 sample_mflix数据库。要学习;了解如何创建免费的MongoDB Atlas 群集并加载示例数据集,请参阅MongoDB .NET/ C#驱动程序文档中的入门。
以下 Movie 类对 sample_mflix.movies 集合中的文档进行建模:
[] public class Movie { [] public ObjectId Id { get; set; } [] public string Title { get; set; } = null!; [] public int? Year { get; set; } [] public int? Runtime { get; set; } [] public string? Rated { get; set; } [] public int Metacritic { get; set; } [] public string? Plot { get; set; } [] public string? Type { get; set; } [] public string[]? Cast { get; set; } [] public string[]? Directors { get; set; } [] public string[]? Writers { get; set; } [] public ImdbData? Imdb { get; set; } }
要使用MongoDB .NET/ C#驾驶员将$set PipelineDefinition阶段添加到聚合管道,请对 对象调用 UnionWith() 方法。
以下示例创建一个管道阶段,用于匹配标题为 "The Godfather" 的 Movie 文档,并将其 Rated 字段设置为 "UNRATED":
var pipeline = new EmptyPipelineDefinition<Movie>() .Match(Builders<Movie>.Filter.Eq(m => m.Title, "The Godfather")) .Set(Builders<Movie>.SetFields.Set(m => m.Rated, "UNRATED"));
本页上的 Node.js 示例使用 Atlas 示例数据集中的 sample_mflix数据库。要学习如何创建免费的MongoDB Atlas 集群并加载示例数据集,请参阅MongoDB Node.js驱动程序文档中的入门。
要使用MongoDB Node.js驱动程序将 $set 阶段添加到聚合管道,请在管道对象中使用 $set操作符。
以下示例创建一个管道阶段,将每个 movie 文档中的 lastupdated 字段的值设置为 Date 对象的值。然后,示例运行聚合管道:
const pipeline = [{ $set: { lastupdated: new Date() } }]; const cursor = collection.aggregate(pipeline); return cursor;
了解详情
有关相关阶段,请参阅 $addFields。