Подтвердить что ты не робот

Включить все существующие поля и добавить новые поля в документ

Я хотел бы определить этап агрегации $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...
]

Есть ли что-то вроде ключевого слова "включить все поля", которое я могу использовать в этом случае, или каким-либо другим способом избежать необходимости перечислять каждое поле отдельно?

4b9b3361

Ответ 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);