J'aimerais définir une étape d'agrégation de $ projet dans laquelle je peux lui demander d'ajouter un nouveau champ et d'inclure tous les champs existants, sans avoir à répertorier tous les champs existants.
Mon document ressemble à ceci, avec de nombreux champs:
{
obj: {
obj_field1: "hi",
obj_field2: "hi2"
},
field1: "a",
field2: "b",
...
field26: "z"
}
Je veux faire une opération d'agrégation comme ceci:
[
{
$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...
]
Y a-t-il quelque chose comme un mot clé "inclure tous les champs" que je puisse utiliser dans ce cas, ou un autre moyen d'éviter de lister chaque champ séparément?
Dans 4.2+, vous pouvez utiliser le $set
opérateur de pipeline d'agrégation auquel rien d'autre qu'un alias à $addFields
ajouté dans 3.4
Le
$addFields
_ stage équivaut à$project
étape qui spécifie explicitement tous les champs existants dans les documents d’entrée et ajoute les nouveaux champs.
db.collection.aggregate([
{ "$addFields": { "custom_field": "$obj.obj_field1" } }
])
Vous pouvez utiliser $$ ROOT pour référencer le document racine. Conservez tous les champs de ce document dans un champ et essayez ensuite de l'obtenir (selon votre système client: Java, C++, ...)
[
{
$project: {
custom_field: "$obj.obj_field1",
document: "$$ROOT"
}
},
... //group, match, and whatever...
]
>>> Il y a quelque chose comme le mot clé "inclure tous les champs" que je peux utiliser dans ce cas ou une autre solution?
Malheureusement, il n'y a pas d'opérateur pour "inclure tous les champs" dans l'opération d'agrégation. La seule raison pour laquelle, étant donné que l'agrégation est généralement créée pour regrouper/calculer des données à partir de champs de collection (somme, moy, etc.) et renvoyer tous les champs de la collection n'est pas un objectif direct.
A partir de la version 2.6.4, Mongo DB n’a pas cette fonctionnalité pour le $project
pipeline d'agrégation. À partir de docs pour $project
:
Transmet les documents contenant uniquement les champs spécifiés à la prochaine étape du pipeline. Les champs spécifiés peuvent être des champs existants des documents d'entrée ou des champs nouvellement calculés.
et
Le champ _id est, par défaut, inclus dans les documents de sortie. Pour inclure les autres champs des documents d'entrée dans les documents de sortie, vous devez spécifier explicitement l'inclusion dans $ project.
Pour ajouter de nouveaux champs à votre document, vous pouvez utiliser $ addFields
[de docs] [1]
et à tous les champs de votre document, vous pouvez utiliser $$ 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/
selon @Deka, pour le pilote c # mongodb 2.5, vous pouvez obtenir le document groupé avec toutes les clés comme ci-dessous;
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);