Включить все существующие поля и добавить новые поля в документ
Я хотел бы определить этап агрегации $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...
]
Есть ли что-то вроде ключевого слова "включить все поля", которое я могу использовать в этом случае, или каким-либо другим способом избежать необходимости перечислять каждое поле отдельно?
Ответы
Ответ 1
В 4. 2+, вы можете использовать $set
оператора агрегации трубопровода, который ничего, кроме псевдонима до $addFields
добавленным в 3.4
Этап $addFields
эквивалентен этапу $project
который явно указывает все существующие поля во входных документах и добавляет новые поля.
db.collection.aggregate([
{ "$addFields": { "custom_field": "$obj.obj_field1" } }
])
Ответ 2
Вы можете использовать $$ ROOT для ссылки на корневой документ. Сохраните все поля этого документа в поле и попытайтесь получить его после этого (в зависимости от вашей клиентской системы: Java, С++,...)
[
{
$project: {
custom_field: "$obj.obj_field1",
document: "$$ROOT"
}
},
... //group, match, and whatever...
]
Ответ 3
→ > Что-то вроде ключевого слова "включить все поля", которое я могу использовать в этом случае или какое-то другое решение?
К сожалению, нет оператора для включения всех полей в операцию агрегации. Единственная причина, почему, поскольку агрегация в основном создается для группировки/вычисления данных из полей сбора (sum, avg и т.д.) И возврата всех полей коллекции не является прямой целью.
Ответ 4
Начиная с версии 2.6.4, Mongo DB не имеет такой возможности для конвейера агрегации $project
. Из docs для $project
:
Проходит по документам только с указанными полями на следующий этап в конвейере. Указанные поля могут быть существующими полями из входных документов или вновь вычисленных полей.
и
Поле _id по умолчанию включено в выходные документы. Чтобы включить другие поля из входных документов в выходные документы, вы должны явно указать включение в $project.
Ответ 5
в соответствии с ответом @Deka, для С# mongodb driver 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);