包括所有现有字段并向文档添加新字段

sam*_*uis 109 mongodb mongodb-query aggregation-framework

我想定义一个$ project聚合阶段,我可以指示它添加一个新字段并包含所有现有字段,而不必列出所有现有字段.

我的文档看起来像这样,有很多字段:

{
    obj: {
        obj_field1: "hi",
        obj_field2: "hi2"
    },
    field1: "a",
    field2: "b",
    ...
    field26: "z"
}
Run Code Online (Sandbox Code Playgroud)

我想做一个像这样的聚合操作:

[
    {
        $project: {
            custom_field: "$obj.obj_field1",
            //the next part is that I don't want to do
            field1: 1,
            field2: 1,
            ...
            field26: 1
        }
    },
    ... //group, match, and whatever...
]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我可以使用类似"包含所有字段"的关键字,还是以其他方式避免必须单独列出每个字段?

sty*_*ane 149

从MongoDB 3.4开始,我们可以使用$set聚合管道运算符来执行此操作:

$addFields阶段等效于$addFields显式指定输入文档中所有现有字段并添加新字段的阶段.

db.collection.aggregate([
    { "$addFields": { "custom_field": "$obj.obj_field1" } }
])
Run Code Online (Sandbox Code Playgroud)

  • 我发现如果您指定相同的字段名称,它甚至可以替换一个字段 (3认同)
  • 知道如何在C#驱动程序中使用它吗?似乎它不存在 (2认同)

Dek*_*eka 72

您可以使用$$ ROOT来引用根文档.将此文档的所有字段保留在一个字段中,然后尝试获取它(取决于您的客户端系统:Java,C++,...)

 [
    {
        $project: {
            custom_field: "$obj.obj_field1",
            document: "$$ROOT"

        }
    },
    ... //group, match, and whatever...
]
Run Code Online (Sandbox Code Playgroud)

  • 但是这将创建一个名为`document`的嵌入式文档,这是一个创建一个合并文档的选项会更好...... (14认同)
  • 屏住呼吸.MongoDB 3.4将附带[$ addFields聚合阶段](https://jira.mongodb.org/browse/SERVER-5781).请参见http://stackoverflow.com/a/24557029/4653485. (10认同)
  • 有没有人知道在不创建嵌入文档的情况下通过所有键值对的解决方案? (2认同)

Dee*_*rma 10

要向文档添加新字段,您可以使用$addFields

来自文档

对于文档中的所有字段,您可以使用 $$ROOT

db.collection.aggregate([

{ "$addFields": { "custom_field": "$obj.obj_field1" } },
{ "$group": {
        _id : "$field1",
        data: { $push : "$$ROOT" }
    }}
])
Run Code Online (Sandbox Code Playgroud)


小智 7

>>>在这种情况下我可以使用"包括所有字段"关键字或其他解决方案吗?

不幸的是,没有运营商在聚合操作中"包括所有字段".唯一的原因,原因,因为聚合主要是为了从集合字段(sum,avg等)分组/计算数据并返回所有集合的字段而不是直接目的.