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

问题描述 投票:96回答:5

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

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

{
    obj: {
        obj_field1: "hi",
        obj_field2: "hi2"
    },
    field1: "a",
    field2: "b",
    ...
    field26: "z"
}

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

[
    {
        $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...
]

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

mongodb mongodb-query aggregation-framework
5个回答
130
投票

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

$addFields阶段相当于$project阶段,它明确指定输入文档中的所有现有字段并添加新字段。

db.collection.aggregate([
    { "$addFields": { "custom_field": "$obj.obj_field1" } }
])

66
投票

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

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

        }
    },
    ... //group, match, and whatever...
]

6
投票

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

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


2
投票

从版本2.6.4开始,Mongo DB没有$project聚合管道的这样的功能。从docs$project

将仅包含指定字段的文档传递到管道中的下一个阶段。指定的字段可以是输入文档或新计算字段中的现有字段。

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


0
投票

根据@Deka的回复,对于c#mongodb驱动程序2.5,您可以使用以下所有键获取分组文档;

var group = new BsonDocument
{
 { "_id", "$groupField" },
 { "_document", new BsonDocument { { "$first", "$$ROOT" } } }
};

ProjectionDefinition<BsonDocument> projection = new BsonDocument{{ "document", "$_document"}};
var result = await col.Aggregate().Group(group).Project(projection).ToListAsync();

// For demo first record 
var fistItemAsT = BsonSerializer.Deserialize<T>(result.ToArray()[0]["document"].AsBsonDocument);
© www.soinside.com 2019 - 2024. All rights reserved.