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

我想定义一个 $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...
]

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

103770 次浏览

有一些类似“包含所有字段”的关键字,我可以在这种情况下使用或其他解决方案?

不幸的是,在聚合操作中没有“包含所有字段”的操作符。因为创建聚合主要是为了对来自集合字段(sum、 avg 等)的数据进行分组/计算,并返回集合的所有字段,所以创建聚合的唯一原因并非直接目的。

在2.6.4版本中,MongoDB 对于 $project聚合管道没有这样的特性。从 医生$project:

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

还有

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

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

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


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

在4.2 + 中,您可以使用 $set聚合管道运算符,它只不过是3.4中添加的 $addFields的别名

$addFields stage 相当于 $project stage,它显式地指定输入文档中的所有现有字段并添加新字段。

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

根据@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);

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

来自医生

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

db.collection.aggregate([


{ "$addFields": { "custom_field": "$obj.obj_field1" } },
{ "$group": {
_id : "$field1",
data: { $push : "$$ROOT" }
}}
])