2012-03-29 3 views
1

J'ai un document de commande qui ressemble à ceci

{ 
    "_id" : ObjectId("4f70ba6dfb59c87f6b07a1ad"), 
    "state" : "CART", "storeId" : "1", "userId" : "johndoe", 
    "orderItems" : [ 
     { 
      "productId" : "169", 
      "offerId" : "112233", 
      "sku" : "product-sku-1", 
      "name" : "Product Awesome A", 
      "quantity" : 1, 
      "retailPrice" : 495, 
      "salePrice" : 395 
     }, 
     { 
      "productId" : "170", 
      "offerId" : "112234", 
      "sku" : "product-sku-2", 
      "name" : "Product Awesome B", 
      "quantity" : 1, 
      "retailPrice" : 595, 
      "salePrice" : 495 
     } 
    ] 
} 

Problème: Je veux trouver un OrderItem qui a soit productId ou sku avec la valeur du produit-sku- 1 et régler la quantité à 2.

Alors, j'ai essayé le

db.order.update(
    { 
     "userId":"johndoe", "state":"CART", 
     $or: [ 
      {"orderItems.productId":"product-sku-1"}, 
      {"orderItems.sku":"product-sku-1"} 
     ] 
    }, 
    { 
     $set : {"orderItems.$.quantity":2} 
    } 
) 

suivante Cela me donne une erreur

"can't append to array using string field name [$]" 

Si je retire la ou condition et d'interrogation sur un seul champ du document sous comme ci-dessous, tout fonctionne bien comme prévu avec la quantité fixée à 2.

db.order.update(
    { 
     "userId":"johndoe", "state":"CART", 
     "orderItems.sku":"product-sku-1" 
    }, 
    { 
     $set : {"orderItems.$.quantity":2} 
    } 
) 

Ma demande reçoit soit sku ou productId comme le champ de l'identifiant. Je ne sais pas si c'est un sku ou productId au moment de la requête. Donc, je dois être en mesure d'interroger sur l'un des champs dans le sous-document et mettre à jour la quantité.

Notez que j'ai besoin de la mise à jour effectuée de manière atomique. Je ne veux vraiment pas faire deux mises à jour l'une après l'autre.

Ai-je raté quelque chose ici? Y a-t-il une autre façon élégante de le faire?

+2

J'ai trouvé la réponse après avoir lu attentivement la différence entre le notation et les sous-objets http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+ dans + Objets% 29 – VikramG

Répondre

4

J'ai trouvé la réponse après avoir lu attentivement la différence entre la notation par points et sub-objects in this post. Je suis venu à la solution suivante:

db.order.update(
    { 
     "userId":"johndoe", "state":"CART", 
     "orderItems" : { 
      $elemMatch : { $or:[{"productId":"product-sku-1"}, {"sku":"product-sku-1"}] } 
     } 
    }, 
    { 
     $set : {"orderItems.$.quantity":2} 
    } 
) 
0

Cette utilisation de $ n'est pas supportée. La requête $ ou ne définit pas la valeur de l'opérateur $ positional, donc MongoDB pense que vous recherchez un champ nommé "$", ce qui est interdit.

Je suggère que vous émettiez simplement deux mises à jour, un filtrage par productId, l'autre filtrage par sku. Une seule des mises à jour va réellement changer un document.

+0

J'utilise actuellement l'approche des mises à jour multiples. Je voulais voir s'il y avait un moyen de le faire dans une mise à jour. Merci d'avoir pris le temps d'expliquer l'erreur lancée. – VikramG

Questions connexes