Docs 菜单
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 ,即上一阶段计算的imdbScoreScaledruntimeHours 之和。

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

以下聚合操作将新字段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字段替换为字符串 "movie"

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

可以使用$set$concatArrays 表达式向现有大量字段添加元素。以下操作使用$setgenres 字段替换为一个新大量,该数组的元素是当前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 集合中的文档进行建模:

[BsonIgnoreExtraElements]
public class Movie
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("title")]
public string Title { get; set; } = null!;
[BsonElement("year")]
public int? Year { get; set; }
[BsonElement("runtime")]
public int? Runtime { get; set; }
[BsonElement("rated")]
public string? Rated { get; set; }
[BsonElement("metacritic")]
public int Metacritic { get; set; }
[BsonElement("plot")]
public string? Plot { get; set; }
[BsonElement("type")]
public string? Type { get; set; }
[BsonElement("cast")]
public string[]? Cast { get; set; }
[BsonElement("directors")]
public string[]? Directors { get; set; }
[BsonElement("writers")]
public string[]? Writers { get; set; }
[BsonElement("imdb")]
public ImdbData? Imdb { get; set; }
}

要使用MongoDB .NET/ C#驱动程序将 $set 阶段添加到聚合管道,请对 PipelineDefinition对象调用 Set() 方法。

以下示例创建一个管道阶段,用于匹配标题为 "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"));
{ "_id" : "...", "title" : "The Godfather", "runtime" : 175, "rated" : "UNRATED", "metacritic" : 100 }

本页上的 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 指南。

后退

$searchMeta

在此页面上