Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs 菜单
Docs 主页
/ /

$ 项目 (聚合阶段)

$project

将带所请求字段的文档传递至管道中的下个阶段。指定的字段可以是输入文档中的已有字段或新计算的字段。

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

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

  • MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本

  • MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本

$project 阶段具有以下原型形式:

{ $project: { <specification(s)> } }

$project 采用的文档可以指定包含字段、抑制 _id 字段、添加新字段以及重置现有字段的值。您也可以指定排除字段。

$project 规范有以下几种形式:

形式
说明

<field>: <1 or true>

指定包含字段。非零整数也被视为 true

_id: <0 or false>

指定抑制 _id 字段。

要有条件地排除字段,请改用REMOVE 变量。有关详细信息,请参阅有条件地排除字段。

<field>: <expression>

添加新字段或重置现有字段的值。

如果表达式的计算结果为 $$REMOVE,则在输出中排除该字段。 有关详细信息,请参阅有条件地排除字段。

<field>: <0 or false>

指定排除某个字段。

要有条件地排除字段,请改用REMOVE 变量。有关详细信息,请参阅有条件地排除字段。

如果指定排除_id 以外的字段,则不能使用任何其他$project 规范形式。此限制应用用于使用REMOVE 变量有条件地排除字段。

要排除字段,还可以使用$unset 阶段。

  • 默认情况下,_id 字段包含在输出文档中。要在输出文档中包含输入文档中的任何其他字段,必须在 $project 中明确指定包含该字段。

  • 如果您指定包含的字段在文档中并不存在,那么 $project 将忽略该字段包含,同时不会将该字段添加到文档中。

默认情况下,_id 字段包含在输出文档中。要从输出文档中排除 _id 字段,必须在 $project 中明确指定抑制 _id 字段。

如果指定排除一个或多个字段,则所有其他字段均为在输出文档中返回。

{ $project: { "<field1>": 0, "<field2>": 0, ... } } // Return all but the specified fields

如果指定排除 _id 之外的字段,那么您不能使用任何其他 $project 规范形式:即,如果排除字段,那么您不能同时指定包含字段、重置现有字段的值或添加新字段。此限制不适用于使用 REMOVE 变量有条件地排除字段。

另请参阅 $unset 阶段,以排除字段。

您可以在聚合表达式中使用变量 REMOVE 来有条件地抑制字段。有关示例,请参阅有条件地排除字段

注意

MongoDB 还提供 $addFields 向文档添加新字段。

要添加新字段或重置现有字段的值,请指定字段名称并将其值设置为某个表达式。 有关表达式的更多信息,请参阅表达式。

要将字段值直接设置为数值或布尔文字,而不是将该字段设置为可解析为文字的表达式,请使用 $literal 操作符。否则,$project 将数字或布尔文字视为包含或排除该字段的标志。

有效地重命名字段的方式:指定新字段并将其值设置为现有字段的字段路径。

$project 阶段支持使用方括号 [] 直接创建新的数组字段。如果指定文档中不存在的数组字段,此操作将替换 null 作为该字段的值。有关示例,请参阅投影新的数组字段

不能将大量索引与$project 阶段一起使用。

在嵌入式文档中投影或添加/重置字段时,可以使用点符号,如

"contact.address.country": <1 or 0 or expression>

或者您可以嵌套字段:

contact: { address: { country: <1 or 0 or expression> } }

嵌套字段时,不能在嵌入式文档中使用点符号来指定字段,例如contact: { "address.country": <1 or 0 or expression> } 无效

不能在同一投影中同时指定嵌入式文档和嵌入式文档中的字段。

以下 $project 阶段失败并出现 Path collision 错误,原因是它试图投影嵌入的 contact 文档和 contact.address.country 字段:

{ $project: { contact: 1, "contact.address.country": 1 } }

无论指定父文档和嵌入式字段的顺序如何,错误都会发生。以下 $project 失败并出现同样的错误:

{ $project: { "contact.address.country": 1, contact: 1 } }

当您使用 $project 阶段时,它通常应该是管道中的最后一个阶段,用于指定要返回给客户端的字段。

在管道的开头或中间使用 $project 阶段来减少传递到后续管道阶段的字段数量不太可能提高性能,因为数据库会自动执行此优化。

如果 $project 阶段传递的是空文档,MongoDB 将返回错误。

例如,运行以下管道会产生错误:

db.myCollection.aggregate( [ {
$project: { }
} ] )

不能将大量索引与$project 阶段一起使用。

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

以下$project 阶段仅包括_idtitlerated 字段:

db.movies.aggregate( [
{ $match: { title: "The Great Train Robbery" } },
{ $project: { title: 1, rated: 1 } },
{ $limit: 1 }
] )
[
{
_id: ObjectId('573a1390f29313caabcd42e8'),
title: 'The Great Train Robbery',
rated: 'TV-G'
}
]

MongoDB默认包含_id 字段。要从_id $project阶段排除 字段,请在投影文档中将_id 字段设立为0

以下$project 阶段不包括_id 字段,但包括titlerated 字段:

db.movies.aggregate( [
{ $match: { title: "The Great Train Robbery" } },
{ $project : { _id: 0, title : 1, rated : 1 } },
{ $limit: 1 }
] )
[ { title: 'The Great Train Robbery', rated: 'TV-G' } ]

以下 $project 阶段从输出中排除 rated 字段:

db.movies.aggregate( [
{ $match: { title: "The Great Train Robbery" } },
{ $project : { "rated": 0 } },
{ $limit: 1 }
] )

或者,使用$unset 阶段排除字段。

以下 $project 阶段从输出中排除 imdb.idtype 字段:

db.movies.aggregate( [
{ $match: { title: "The Great Train Robbery" } },
{ $project: { "imdb.id": 0, "type": 0 } },
{ $limit: 1 }
] )
[
{
_id: ObjectId('573a1390f29313caabcd42e8'),
plot: 'A group of bandits stage a brazen train hold-up, only to find a determined posse hot on their heels.',
genres: [ 'Short', 'Western' ],
runtime: 11,
cast: [
'A.C. Abadie',
"Gilbert M. 'Broncho Billy' Anderson",
'George Barnes',
'Justus D. Barnes'
],
poster: 'https://m.media-amazon.com/images/M/MV5BMTU3NjE5NzYtYTYyNS00MDVmLWIwYjgtMmYwYWIxZDYyNzU2XkEyXkFqcGdeQXVyNzQzNzQxNzI@._V1_SY1000_SX677_AL_.jpg',
title: 'The Great Train Robbery',
fullplot: "Among the earliest existing films in American cinema - notable as the first film that presented a narrative story to tell - it depicts a group of cowboy outlaws who hold up a train and rob the passengers. They are then pursued by a Sheriff's posse. Several scenes have color included - all hand tinted.",
languages: [ 'English' ],
released: ISODate('1903-12-01T00:00:00.000Z'),
directors: [ 'Edwin S. Porter' ],
rated: 'TV-G',
awards: { wins: 1, nominations: 0, text: '1 win.' },
lastupdated: '2015-08-13 00:27:59.177000000',
year: 1903,
imdb: { rating: 7.4, votes: 9847 },
countries: [ 'USA' ],
tomatoes: {
viewer: { rating: 3.7, numReviews: 2559, meter: 75 },
fresh: 6,
critic: { rating: 7.6, numReviews: 6, meter: 100 },
rotten: 0,
lastUpdated: ISODate('2015-08-08T19:16:10.000Z')
},
num_mflix_comments: 0
}
]

或者,您可以在文档中嵌套排除规范:

db.movies.aggregate( [
{ $match: { title: "The Great Train Robbery" } },
{ $project: { "imdb": { "id": 0 }, "type" : 0 } },
{ $limit: 1 }
] )
[
{
_id: ObjectId('573a1390f29313caabcd42e8'),
plot: 'A group of bandits stage a brazen train hold-up, only to find a determined posse hot on their heels.',
genres: [ 'Short', 'Western' ],
runtime: 11,
cast: [
'A.C. Abadie',
"Gilbert M. 'Broncho Billy' Anderson",
'George Barnes',
'Justus D. Barnes'
],
poster: 'https://m.media-amazon.com/images/M/MV5BMTU3NjE5NzYtYTYyNS00MDVmLWIwYjgtMmYwYWIxZDYyNzU2XkEyXkFqcGdeQXVyNzQzNzQxNzI@._V1_SY1000_SX677_AL_.jpg',
title: 'The Great Train Robbery',
fullplot: "Among the earliest existing films in American cinema - notable as the first film that presented a narrative story to tell - it depicts a group of cowboy outlaws who hold up a train and rob the passengers. They are then pursued by a Sheriff's posse. Several scenes have color included - all hand tinted.",
languages: [ 'English' ],
released: ISODate('1903-12-01T00:00:00.000Z'),
directors: [ 'Edwin S. Porter' ],
rated: 'TV-G',
awards: { wins: 1, nominations: 0, text: '1 win.' },
lastupdated: '2015-08-13 00:27:59.177000000',
year: 1903,
imdb: { rating: 7.4, votes: 9847 },
countries: [ 'USA' ],
tomatoes: {
viewer: { rating: 3.7, numReviews: 2559, meter: 75 },
fresh: 6,
critic: { rating: 7.6, numReviews: 6, meter: 100 },
rotten: 0,
lastUpdated: ISODate('2015-08-08T19:16:10.000Z')
},
num_mflix_comments: 0
}
]

或者,使用$unset 阶段排除字段。

可以在聚合表达式中使用变量 REMOVE 来有条件地隐藏字段。

$projectREMOVEimdb.votes如果 字段等于null 或是空字符串,则以下 阶段使用 变量排除 字段:

db.movies.aggregate( [
{ $match: { title: "This Is Spinal Tap" } },
{
$project: {
title: 1,
"imdb.rating": 1,
"imdb.id": 1,
"imdb.votes": {
$cond: {
if: { $in: [ "$imdb.votes", [ null, "" ] ] },
then: "$$REMOVE",
else: "$imdb.votes"
}
}
}
},
{ $limit: 1 }
] )
[
{
_id: ObjectId('573a1398f29313caabce94a3'),
title: 'This Is Spinal Tap',
imdb: { rating: 8, id: 88258 }
}
]

由于 imdb.votes 在此文档中为空字符串,因此MongoDB会从输出中排除该字段。

提示

与 $addFields 的比较

您可以使用 $addFields$project 阶段删除文档字段。最佳方法取决于您的管道以及您希望保留多少原始文档。

要查看在 $addFields 阶段中使用 $$REMOVE 的示例,请参阅删除字段

movies集合中的文档包含嵌入式imdb ratingvotesid文档,其中包含 、 和 字段。要仅包含rating 文档中的imdb 字段,请使用点表示法:

db.movies.aggregate( [
{ $match: { title: "The Great Train Robbery" } },
{ $project: { "imdb.rating": 1 } },
{ $limit: 1 }
] )
[
{
_id: ObjectId('573a1390f29313caabcd42e8'),
imdb: { rating: 7.4 }
}
]

或者,将包含规范嵌套在文档中:

db.movies.aggregate( [
{ $match: { title: "The Great Train Robbery" } },
{ $project: { imdb: { rating: 1 } } },
{ $limit: 1 }
] )
[
{
_id: ObjectId('573a1390f29313caabcd42e8'),
imdb: { rating: 7.4 }
}
]

以下$project 阶段添加leadActorreleaseYear 字段:

db.movies.aggregate( [
{ $match: { title: "The Great Train Robbery" } },
{
$project: {
title: 1,
leadActor: { $arrayElemAt: [ "$cast", 0 ] },
releaseYear: "$year"
}
},
{ $limit: 1 }
] )
[
{
_id: ObjectId('573a1390f29313caabcd42e8'),
title: 'The Great Train Robbery',
leadActor: 'A.C. Abadie',
releaseYear: 1903
}
]

以下操作将 yearruntime 字段投影为新 myArray字段中的元素:

db.movies.aggregate( [
{ $match: { title: "The Great Train Robbery" } },
{ $project: { myArray: [ "$year", "$runtime" ] } },
{ $limit: 1 }
] )
[
{
_id: ObjectId('573a1390f29313caabcd42e8'),
myArray: [ 1903, 11 ]
}
]

如果数组规范包含文档中不存在的字段,则该操作将 null 替换为该字段的值。

例如,给定与上面相同的文档,以下操作将字段 yearruntime 和不存在的字段 $someField 投影为新字段 myArray 中的元素:

db.movies.aggregate( [
{ $match: { title: "The Great Train Robbery" } },
{ $project: { myArray: [ "$year", "$runtime", "$someField" ] } },
{ $limit: 1 }
] )
[
{
_id: ObjectId('573a1390f29313caabcd42e8'),
myArray: [ 1903, 11, null ]
}
]

本页上的C#示例使用Atlas示例数据集中的 sample_mflix数据库。要学习;了解如何创建免费的MongoDB Atlas 群集并加载示例数据集,请参阅MongoDB .NET/ C#驱动程序文档中的入门

以下 MovieImdbData 类对 sample_mflix.movies集合中的文档进行建模:

public class Movie
{
public ObjectId Id { get; set; }
public string Title { get; set; }
public List<string> Genres { get; set; }
public List<string> Directors { get; set; }
public List<string> Writers { get; set; }
public string Type { get; set; }
public string Plot { get; set; }
public ImdbData Imdb { get; set; }
public List<string> Cast { get; set; }
}
public class ImdbData
{
public string Id { get; set; }
public int Votes { get; set; }
public float Rating { get; set; }
}

注意

用于 Pascal Case 的 ConventionPack

此页面上的 C# 类在其属性名称中使用 Pascal 命名法,而 MongoDB 集合中的字段名称则使用 camel 命名法。为了解决这种差异,可以在应用程序启动时使用以下代码注册一个 ConventionPack

var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);

要使用 MongoDB .NET/C# 驱动程序将 $project 阶段添加到MongoDB 聚合管道中,请在 PipelineDefinition 对象上调用 Project() 方法,并传递 ProjectionDefinitionBuilder<TDocument> 对象。TDocument 是表示集合中各个文档的类。

以下各节展示了您可以自定义 $project 阶段输出文档的不同方法。

要在使用 .NET/C# 驱动程序时包含特定字段,请在投影构建器上调用 Include() 方法。您可以将 Include() 调用链接起来以包含多个字段。

以下代码示例生成的文档仅包含 _idplottitle 字段:

var pipeline = new EmptyPipelineDefinition<Movie> ()
.Project(
Builders<Movie>.Projection
.Include(m => m.Title)
.Include(m => m.Plot)
);
var result = movieCollection.Aggregate(pipeline).FirstOrDefault();

管道返回以下文档:

{
"_id" : { "$oid" : "573a1390f29313caabcd42e8" },
"plot" : "A group of bandits stage a brazen train hold-up, only to find a
determined posse hot on their heels.",
"title" : "The Great Train Robbery"
}

要在使用 .NET/C# 驱动程序时从结果文档中排除某个字段,请在投影构建器上调用 Exclude() 方法。您可以将 Exclude() 调用链接起来以排除多个字段。

以下代码示例生成一个排除 Type 字段的文档:

var pipeline = new EmptyPipelineDefinition<Movie>()
.Project(
Builders<Movie>.Projection
.Exclude(m => m.Type)
);
var result = movieCollection.Aggregate(pipeline).FirstOrDefault();

默认情况下,结果文档始终包含 _id 字段。以下代码示例生成一个不包含 _id 字段但包含 plottitle 字段的文档:

var pipeline = new EmptyPipelineDefinition<Movie> ()
.Project(
Builders<Movie>.Projection
.Exclude(m => m.Id)
.Include(m => m.Title)
.Include(m => m.Plot)
);
var result = movieCollection.Aggregate(pipeline).FirstOrDefault();

管道生成以下文档:

{
"plot" : "A group of bandits stage a brazen train hold-up, only to find a
determined posse hot on their heels.",
"title" : "The Great Train Robbery"
}

要在使用 .NET/C# 驱动程序时排除嵌入式文档中的某个字段,请调用投影构建器的 Exclude() 方法,并将路径传递给相应的类属性。您可以将 Exclude() 调用链接起来以排除多个字段。

以下代码示例生成一个排除 imdb.idtype 字段的文档:

var pipeline = new EmptyPipelineDefinition<Movie> ()
.Project(
Builders<Movie>.Projection
.Exclude("Imdb.id")
.Exclude(m => m.Type)
);
var result = movieCollection.Aggregate(pipeline).FirstOrDefault();

管道会产生以下输出结果:

{
"plot" : "A group of bandits stage a brazen train hold-up, only to find a
determined posse hot on their heels.",
"title" : "The Great Train Robbery",
...
"imdb" : { "rating" : 7.4000000000000004, "votes" : 9847 }
}

注意

将字符串用于嵌入式 ID 字段

要在嵌入式文档中投影 ID 字段,请将字段名称指定为字符串,而不是 lambda 表达式。

可以在聚合表达式中使用变量 REMOVE 来有条件地隐藏字段:

var stage = new BsonDocument
{
{ "title", 1 },
{ "imdb.id", 1 },
{ "imdb.rating", 1 },
{
"imdb.votes", new BsonDocument("$cond", new BsonDocument
{
{ "if", new BsonDocument("$eq", new BsonArray { "", "$imdb.votes" }) },
{ "then", "$$REMOVE" },
{ "else", "$imdb.votes" }
})
}
};
var pipeline = new EmptyPipelineDefinition<Movie>()
.Project(stage)
.Sample(1);
var result = movieCollection.Aggregate(pipeline).FirstOrDefault();

注意

没有用于条件排除的构建器

前面的示例使用 BsonDocument 对象,因为 .NET/C# 驱动程序不提供用于有条件排除字段的构建器。其他 MongoDB 语言驱动程序可能支持此功能。请参阅 MongoDB 驱动程序文档以了解更多信息。

如果采样文档包含 imdb.votes 字段,管道将返回一个类似于以下的文档:

{
"_id" : { "$oid" : "573a1390f29313caabcd42e8" },
"title" : "The Great Train Robbery",
"imdb" : { "rating" : 7.4000000000000004, "id" : 439, "votes" : 9847 }
}

如果文档不包含 imdb.votes 字段,管道将返回一个类似于以下的文档:

{
"_id" : { "$oid" : "573a1398f29313caabce94a3" },
"title" : "This Is Spinal Tap",
"imdb" : { "rating" : 8.0, "id" : 88258 }
}

要在使用 .NET/C# 驱动程序时在结果文档中包含计算字段,请调用投影构建器的 Expression() 方法,并传递一个包含计算字段的表达式。为了增加类型安全性,您可以为结果文档定义一个模型类,如下所示的 ProjectedMovie 类:

public class ProjectedMovie
{
public ObjectId Id { get; set; }
public string Title { get; set; }
public string LeadActor { get; set; }
public List<string> Crew { get; set; }
}

以下代码示例生成一个包含多个计算字段的文档:

var pipeline = new EmptyPipelineDefinition<Movie>()
.Project(
Builders<Movie>
.Projection
.Expression(m => new ProjectedMovie
{
Id = m.Id,
Title = m.Title,
LeadActor = m.Cast[0],
})
);
var result = movieCollection.Aggregate(pipeline).FirstOrDefault();

管道生成以下文档:

{
"_id" : { "$oid" : "573a1390f29313caabcd42e8" },
"title" : "The Great Train Robbery",
"leadActor" : "A.C. Abadie",
...
}

在使用 .NET/C# 驱动程序时,要在结果文档中投影新的数组字段,请在投影构建器上调用 Expression() 方法,并传递一个包含新数组字段的表达式。为了增加类型安全性,您可以为结果文档定义一个模型类,如下所示的 ProjectedMovie 类:

public class ProjectedMovie
{
public ObjectId Id { get; set; }
public string Title { get; set; }
public string LeadActor { get; set; }
public List<string> Crew { get; set; }
}

以下代码示例生成的文档包含一个新数组字段 crew,其中包含来自 directorswriters 字段的值:

var pipeline = new EmptyPipelineDefinition<Movie> ()
.Project(
Builders<Movie>
.Projection
.Expression(m => new ProjectedMovie
{
Id = m.Id,
Title = m.Title,
LeadActor = m.Cast[0],
Crew = m.Directors.Concat(m.Writers).ToList()
}
)
)
.Sample(1);
var result = movieCollection.Aggregate(pipeline).FirstOrDefault();

管道返回类似于以下内容的文档:

{
"_id" : { "$oid" : "573a1395f29313caabce2297" },
"title" : "The Chalk Garden",
"leadActor" : "Deborah Kerr",
"crew" : ["Ronald Neame", "John Michael Hayes (screenplay)", "Enid Bagnold (from the play by)"]
}

如果数组规范包含文档中不存在的字段,则管道会将 null 替换为该字段的值。例如,以下代码示例将字段 directorswriters 和一个不存在的字段 makeupArtists 作为名为 crew 的新字段中的元素进行投影:

var stage = new BsonDocument
{
{ "crew", new BsonArray { "$directors", "$writers", "$makeupArtists" } }
};
var pipeline = new EmptyPipelineDefinition<Movie>()
.Project(stage)
.Sample(1);
var result = movieCollection.Aggregate(pipeline).FirstOrDefault();

管道返回类似于以下内容的文档:

{
"_id" : { "$oid" : "573a1399f29313caabced0d9" },
"crew" : [["Bill Kroyer"], ["Jim Cox (screenplay)", "Diana Young (original stories)"], null]
}

注意

构建器类防止字段缺失

前面的示例使用 BsonDocument 对象,因为如果您尝试使用生成器将缺少的字段添加到数组中,.NET/C# 驱动程序会引发编译时错误。其他 MongoDB 语言驱动程序可能支持此功能。请参阅 MongoDB 驱动程序文档以了解更多信息。

本页上的 Node.js 示例使用 Atlas 示例数据集中的 sample_mflix数据库。要学习如何创建免费的MongoDB Atlas 集群并加载示例数据集,请参阅MongoDB Node.js驱动程序文档中的入门

要使用MongoDB Node.js驱动程序将 $project 阶段添加到聚合管道,请在管道对象中使用 $project操作符。

以下各节展示如何自定义 $project 阶段的输出文档。

要包括特定字段,请在 $project 阶段将字段的值设置为 1

以下示例返回仅包含 _idplottitle 字段的文档:

const pipeline = [
{
$project: {
title: 1,
plot: 1
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

输出文档类似于以下示例:

{
_id: new ObjectId('573a1390f29313caabcd42e8'),
plot: 'A group of bandits stage a brazen train hold-up, only to find a
determined posse hot on their heels.',
title: 'The Great Train Robbery'
}

要排除特定字段,请在 $project 阶段将字段的值设置为 0

以下示例返回排除 type 字段的文档:

const pipeline = [
{
$project: {
type: 0
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

默认情况下,结果文档始终包含 _id 字段。以下示例返回不包含 _id 字段但包含 plottitle 字段的文档:

const pipeline = [
{
$project: {
_id: 0,
title: 1,
plot: 1
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

输出文档类似于以下示例:

{
plot: 'A group of bandits stage a brazen train hold-up, only to find a
determined posse hot on their heels.',
title: 'The Great Train Robbery'
}

要排除嵌入式文档中的字段,请在 $project 阶段将字段路径的值设置为 0

注意

使用字符串作为嵌入字段

要在嵌入式文档中投影字段,请将字段路径指定为字符串。

以下示例返回排除 imdb.idtype 字段的文档:

const pipeline = [
{
$project: {
"imdb.id": 0,
type: 0
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

输出文档类似于以下示例:

{
plot: 'A group of bandits stage a brazen train hold-up, only to find a
determined posse hot on their heels.',
title: 'The Great Train Robbery',
imdb: { rating: 7.4000000000000004, votes: 9847 }
}

要有条件地排除字段,请将包含变量 REMOVE 的条件逻辑分配到字段名称。

const pipeline = [
{
$project: {
title: 1,
"imdb.id": 1,
"imdb.rating": 1,
"imdb.votes": {
$cond: {
if: { $eq: ["$imdb.votes", ""] },
then: "$REMOVE",
else: "$imdb.votes"
}
}
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

如果文档包含 imdb.votes 字段,管道将返回类似于以下示例输出的文档:

{
_id: new ObjectId('573a1390f29313caabcd42e8'),
title: 'The Great Train Robbery',
imdb: { rating : 7.4000000000000004, id: 439, votes: 9847 }
}

如果文档不包含 imdb.votes 字段,管道将返回类似于以下示例输出的文档:

{
_id: new ObjectId('573a1390f29313caabcd42e8'),
title: 'This Is Spinal Tap',
imdb: { rating: 8.0, id: 88258 }
}

要在结果文档中包含计算字段,请将表达式分配给存储结果的字段。

以下示例将 _idtitle 字段投影到同名的新字段中,并计算出新字段 leadActor。然后,该示例返回包含这些字段的文档:

const pipeline = [
{
$project: {
_id: "$_id",
title: "$title",
leadActor: { $arrayElemAt: ["$cast", 0] }
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

输出文档类似于以下示例:

{
_id: new ObjectId('573a1390f29313caabcd42e8'),
title: 'The Great Train Robbery',
leadActor: 'A.C. Abadie'
}

要在结果文档中投影新的数组字段,请将计算新的数组字段的表达式分配给存储数组的字段。

以下示例返回文档包含一个新数组字段 crew 的文档,该字段合并了 directorswriters 字段中的值:

const pipeline = [
{
$project: {
_id: "$_id",
title: "$title",
leadActor: { $arrayElemAt: ["$cast", 0] },
crew: { $concatArrays: ["$directors", "$writers"] }
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

输出文档类似于以下示例:

{
_id: new ObjectId('573a1395f29313caabce2297'),
title: 'The Chalk Garden',
leadActor: 'Deborah Kerr',
crew: ['Ronald Neame', 'John Michael Hayes (screenplay)', 'Enid Bagnold (from the play by)']
}

如果数组规范包含文档中不存在的字段,则管道会将 null 替换为该字段的值。例如,以下示例将字段 directorswriters 和一个不存在的字段 makeupArtists 作为名为 crew 的新字段中的元素进行投影:

const pipeline = [
{
$project: {
crew: ["$directors", "$writers", "$makeupArtists"]
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

输出文档类似于以下示例:

{
_id: new ObjectId('573a1399f29313caabced0d9'),
crew: [['Bill Kroyer'], ['Jim Cox (screenplay)', 'Diana Young (original stories)'], null]
}

如需了解有关常见聚合任务的更多信息和详细说明,请参阅完整聚合管道教程

要进一步了解此页面上的方法,请参阅以下指南:

后退

$planCacheStats

在此页面上