182 votes

Inclure tous les champs existants et ajouter de nouveaux champs au document

Je voudrais définir un stade d'agrégation de $projet où je peux lui donner l'instruction d'ajouter un nouveau champ et d'inclure tous les champs existants, sans avoir à lister tous les champs existants.

Mon document ressemble à ceci, avec de nombreux champs :

{
    obj: {
        obj_field1: "salut",
        obj_field2: "salut2"
    },
    field1: "a",
    field2: "b",
    ...
    field26: "z"
}

Je veux effectuer une opération d'agrégation comme ceci :

[
    {
        $project: {
            champ_personnalisé: "$obj.obj_field1",
            //la partie suivante est que je ne veux pas faire
            field1: 1,
            field2: 1,
            ...
            field26: 1
        }
    },
    ... //grouper, faire correspondre, et tout ce qui suit...
]

Y a-t-il quelque chose comme un mot-clé "inclure tous les champs" que je peux utiliser dans ce cas, ou un autre moyen d'éviter de devoir lister chaque champ séparément ?

244voto

user3100115 Points 15249

À partir de la version 4.2, vous pouvez utiliser l'opérateur de pipeline d'agrégation $set qui n'est rien d'autre qu'un alias de $addFields ajouté en 3.4

La phase $addFields est équivalente à une phase $project 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" } }
])

96voto

Deka Points 1233

Vous pouvez utiliser $$ROOT pour faire référence au document racine. Gardez tous les champs de ce document dans un champ et essayez de l'obtenir par la suite (selon votre système client : Java, C++, ...)

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

        }
    },
    ... //group, match, et tout ce que vous voulez...
]

10voto

Deeksha Sharma Points 19

Pour ajouter de nouveaux champs à votre document, vous pouvez utiliser $addFields

à partir des docs

et pour tous les champs de votre document, vous pouvez utiliser $$ROOT

db.collection.aggregate([

{ "$addFields": { "champ_personnalisé": "$obj.obj_field1" } },
{ "$group": {
        _id : "$field1",
        données: { $push : "$$ROOT" }
    }}
])

8voto

Victoria Malaya Points 488

Y a-t-il quelque chose comme un 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 une opération d'agrégation. La seule raison, pourquoi, c'est parce que l'agrégation est principalement créée pour regrouper/calculer des données à partir des champs de la collection (somme, moyenne, etc.) et retourner tous les champs de la collection n'est pas l'objectif direct.

3voto

Ghopper21 Points 2709

Dans la version 2.6.4, Mongo DB ne dispose pas d'une telle fonctionnalité pour le pipeline d'agrégation $project. D'après les docs pour $project:

Passe les documents avec seulement les champs spécifiés à l'étape suivante 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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X