MongoDB $项目:保留以前的管道字段

Bra*_*enP 14 mongodb aggregation-framework

在MongoDB投影中,有没有办法指定一些新字段(但同时保留输入到管道投影阶段的字段)?我没有重命名现有的任何字段.

因此,如果我从一个具有'field1'和'field2'的集合开始,并执行以下投影:

{ $project: { field3: { $gt: ['$field1', 10] } } }
Run Code Online (Sandbox Code Playgroud)

我想最终将'field1','field2'和'field3'作为输入提供给下一个阶段,或者从聚合框架输出.

我试图通过排除_id将投影置于排除模式,但这不起作用.

Ste*_*nie 10

MongoDB 2.6引入了一个新的$$ROOT聚合变量,它几乎可以满足您的需求:它将包括在当前管道阶段中处理的完整文档,因此您无需知道或指定要包含的字段.

以您的示例聚合并添加fields投影$$ROOT:

db.pipeline.aggregate(
    { $project: {
        field3: {
            $gt: ['$field1', 10]
        },
        fields: "$$ROOT"
    }}
)
Run Code Online (Sandbox Code Playgroud)

输出将包括新的计算字段和所有原始字段:

{
    "_id" : ObjectId("53b56cc542974939144cee2a"),
    "field3" : false,
    "fields" : {
        "_id" : ObjectId("53b56cc542974939144cee2a"),
        "field1" : 1,
        "field2" : 2,
        "field3" : 3
    }
}
Run Code Online (Sandbox Code Playgroud)

MongoDB 3.3.11引入了可以满足addFields您需求的聚合阶段.请参阅MongoDB问题跟踪器中的此条目:SERVER-5781 - 实现$ addFields聚合阶段,以便使用表达式语言向文档添加新字段.


Fra*_*man 9

在哪里$project需要指定要传递的字段,$addFields将返回所有字段并添加或替换指定的字段.

{ $addFields: { field3: { $gt: ['$field1', 10] } } }
Run Code Online (Sandbox Code Playgroud)

将完全达到你想要的.

请注意,此功能已在Mongo 3.4版中添加.


4J4*_*J41 1

默认情况下仅_id进行投影。您必须指定必须投影哪些其他字段。

{ $project: { field1:1,field2:1, field3: { $gt: ['$field1', 10] } } }
Run Code Online (Sandbox Code Playgroud)

或者

{ $project: { field1:'$field1',field2:'$field2', field3: { $gt: ['$field1', 10] } } }
Run Code Online (Sandbox Code Playgroud)

  • 如果我知道作为投影输入存在的所有字段,那就有效。由于这是自动生成过程的一部分,因此很难(并非不可能,但不理想)在任何给定的投影之前跟踪哪些字段可用。我正在寻找一种可以自动让这些现有字段通过的解决方案(但这可能不存在——只是询问以防万一)。 (2认同)