web-dev-qa-db-ja.com

既存のすべてのフィールドを含め、ドキュメントに新しいフィールドを追加します

すべての既存フィールドをリストすることなく、新しいフィールドを追加してすべての既存フィールドを含めるように指示できる$ 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...
]

この場合に使用できる「すべてのフィールドを含める」キーワード、またはすべてのフィールドを個別にリストする必要のない他の方法のようなものはありますか?

102
samuelluis

4.2以降では、 $set に追加する集約パイプライン演算子 $addFields へのエイリアス以外は使用できません

$addFieldsステージは、入力ドキュメント内のすべての既存フィールドを明示的に指定して新しいフィールドを追加する $project ステージと同等です。

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

$$ ROOT を使用して、ルートドキュメントを参照できます。このドキュメントのすべてのフィールドをフィールドに保持し、その後取得しようとします(クライアントシステムによって異なります:Java、C++、...)

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

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

>>>この場合や他のソリューションで使用できる「すべてのフィールドを含める」キーワードのようなものがありますか?

残念ながら、集計操作に「すべてのフィールドを含める」演算子はありません。集計は主にコレクションフィールド(sum、avgなど)からのデータをグループ化/計算し、コレクションのすべてのフィールドを返すために作成されるため、唯一の理由は直接的な目的ではありません。

7
Victoria Malaya

バージョン2.6.4の時点で、Mongo DBには$project集約パイプラインのためのそのような機能がありません。 docs for $projectから:

指定されたフィールドのみを持つドキュメントをパイプラインの次のステージに渡します。指定されたフィールドは、入力ドキュメントの既存のフィールドまたは新しく計算されたフィールドです。

そして

デフォルトでは、_idフィールドは出力ドキュメントに含まれます。入力ドキュメントのその他のフィールドを出力ドキュメントに含めるには、$ projectに含めることを明示的に指定する必要があります。

3
Ghopper21

ドキュメントに新しいフィールドを追加するには、$ addFieldsを使用できます

[ドキュメントから] [1]

文書内のすべてのフィールドに対して、$$ ROOTを使用できます

db.collection.aggregate([

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


  [1]: https://docs.mongodb.com/master/reference/operator/aggregation/addFields/
0
Deeksha Sharma

@Dekaの回答によると、c#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);
0
mr.byte