2016-05-10 15 views
0

ich ein Dokument mit einem Schema in mongodb haben, die wie folgt aussieht:MongoDB: Aktualisieren des Wertes eines inneren BSON

{ 
    "_id" : ObjectId("572f88424de8c74a69d4558c"), 
    "storecode" : "ABC", 
    "credit" : true, 
    "group" : [ 
     { 
      "group_name" : "Frequent_Buyer", 
      "time" : NumberLong("1462732865712"), 
     } 
    ], 
} 

ich auf dem _id Teil für das erste Objekt im Array unter group hinzufügen möchten so sieht es wie folgt aus:

{ 
    "_id" : ObjectId("572f88424de8c74a69d4558c"), 
    "storecode" : "ABC", 
    "credit" : true, 
    "group" : [ 
     { 
      "group_name" : "Frequent_Buyer", 
      "time" : NumberLong("1462732865712"), 
      "_id" : "573216fee4430577cf35e885" 
     } 
    ], 
} 

Wenn ich diesen Code versuchen sie es nicht:

db.customer.update({ "_id": ObjectId("572f88424de8c74a69d4558c") },{ "$set": { "group.$._id": "573216fee4430577cf35e885"} }) 

WriteResult({ 
    "nMatched" : 0, 
    "nUpserted" : 0, 
    "nModified" : 0, 
    "writeError" : { 
     "code" : 16837, 
     "errmsg" : "The positional operator did not find the match needed from the query. Unexpanded update: groups.$._id" 
    } 
}) 

Allerdings, wenn ich den Code leicht und fügen Sie auf ein zusätzlichen Kriterien für die Abfrage einstellen, funktioniert es:

db.customer.update({ "_id": ObjectId("572f88424de8c74a69d4558c"), "group.groupname": "Frequent_Buyer" },{ "$set": { "group.$._id": "573216fee4430577cf35e885"} }) 

Ergebnisse:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) 

Warum der erste Befehl nicht funktionierte, aber der zweite Befehl Arbeit?

Antwort

1

Dies ist das erwartete Ergebnis. Den Positionsaktualisierungs $ Operator zu verwenden, muß das Array-Feld als Teil des Abfragedokumentes erscheinen, wie in den

documentation. erwähnt

Wenn mit Aktualisierungsoperationen verwendet werden, z.B. db.collection.update() und db.collection.findAndModify(),

  • die Positions $ Operator fungiert als Platzhalter für das erste Element, das das Abfragedokument übereinstimmt, und
  • das Array-Feld als Teil des Abfragedokumentes erscheinen.

Zum Beispiel Wenn Sie Ihre Dokumente mit group_name nicht filtern wollen, einfach group: { "$exists": true } oder "group.0": { "$exists": true } auf Ihre Abfragekriterien hinzuzufügen. Sie fragen dann wie folgt aussehen:

db.customer.updateOne(
    { 
     "_id": ObjectId("572f88424de8c74a69d4558c"), 
     "group.0": { "$exists": true} 
    }, 
    { "$set": { "group.$._id": "573216fee4430577cf35e885" } } 
) 

Last und nicht zuletzt sollten Sie updateOne oder updateMany verwenden, weil Update in der offiziellen Sprache Treiber veraltet.

+0

Im Dokument muss "das Array-Feld als Teil des Abfragedokuments angezeigt werden". bedeutet, dass Sie ein Feld aus dem inneren Array in Ihrer Abfrage haben müssen, um sicherzustellen, dass der Operator $ funktioniert? – Simon

+0

@Simon Nein bedeutet, dass Sie das Array-Feld hier 'group' in Ihren Abfragekriterien benötigen. Ich habe meine Antwort aktualisiert. – styvane

Verwandte Themen