web-dev-qa-db-fra.com

erreur d'opérateur de position mongodb

J'ai des objets comme ça

{
    "_id" : ObjectId("5742be02289512cf98bf63e3"),
    "name" : "test1",
    "name" : "test1",
    "attributes" : [ 
        {
            "name" : "x",
            "color" : "0xd79c9c",
            "_id" : ObjectId("5742be02289512cf98bf63e8")
        }, 
        {
            "name" : "y",
            "color" : "0xd79c9c",
            "_id" : ObjectId("5742be02289512cf98bf63e7")
        }, 
        {
            "name" : "z",
            "color" : "0xd79c9c",
            "_id" : ObjectId("5742be02289512cf98bf63e6")
        }
    ],
    "__v" : 6
}

Et je souhaite mettre à jour tous les documents et définir pour chaque attribut un nouveau champ. Je souhaite donc exécuter une requête unique pour mettre à jour tous les documents à la fois. Je pense que cette requête le fera 

db.spaces.update({}, { $set: { "attributes.0.weight": 2 } }, {multi: true})

Mais lorsque je lance cette requête, j'obtiens une erreur.

"code": 16837,
"errmsg": "L'opérateur de position n'a pas trouvé la correspondance requise dans la requête. Mise à jour non expansée: attributs. $. weight"

Donc je ne comprends pas pourquoi. S'il vous plaît aider

8
Gor

Vous devez inclure le champ tableau dans le document de requête pour pouvoir utiliser lepositional operator.

Par exemple, si vous souhaitez mettre à jour le premier élément de tableau avec { "attributes.name": "x" }, vous pouvez suivre le modèle suivant:

db.spaces.update(
   { "attributes.name": "x" }, // <-- the array field must appear as part of the query document.
   { "$set": { "attributes.$.weight": 2 } },
   { "multi": true }
)

Pour les versions plus récentes de MongoDB 3.2.X, vous pouvez utiliser la méthodeupdateMany()pour mettre à jour plusieurs documents de la collection en fonction du filtre ci-dessus.

16
chridam

L'opérateur de position a besoin d'une correspondance, à partir de la partie correspondance de votre requête de mise à jour.

par exemple:

db.spaces.update({ "attributes.name": "x" }, { $set: { "attributes.0.weight": 2 } }, {multi: true})

ici, le premier paramètre pour l'opération de mise à jour correspondra au tableau attributes où tout élément a une propriété name=="x", pour tout élément correspondant à la condition, l'opérateur de position peut être utilisé pour le mettre à jour.

Donc, parce que name='x', dans ce cas, le premier élément correspondant serait,

{
            "name" : "x",
            "color" : "0xd79c9c",
            "_id" : ObjectId("5742be02289512cf98bf63e8")
        }, 

et il sera mis à jour.

Maintenant, d'après votre question, je comprends que vous souhaitez mettre à jour le document de manière à ce que, dans chaque document, votre premier élément, attribute, obtienne une nouvelle valeur pour weight=2.

vous pouvez faire quelque chose comme

db.spaces.update({ "attributes.name": { $regex: /^(?=[\S\s]{10,8000})[\S\s]*$/ } }, { $set: { "attributes.0.weight": 2 } }, {multi: true})

Ce que nous faisons ici est de faire correspondre tous les éléments d'un attribut de tableau. et nous utilisons l'opérateur de position pour mettre à jour le premier élément de ce tableau

2
Naeem Shaikh