2016-03-22 2 views
0

Ich habe ein Problem mit MongoDB $ set & $ -Operatoren. Ich versuche, ein vorhandenes ArrayMongoDB Bulk.find.update() nicht ändern Array-Objekte, nur neue hinzufügen

Meine Update-Methode sieht wie folgt aus etwa zu ändern (Ich kann nicht die genaue Kopie erhalten, wie es in Clojure/Monger geschrieben):

bulk.find({ 
      _id: 2, 
      channelStatuses.channel: {$eq: "BAR"} 
    }).update({ 
      $set: {"channelStatuses.$.status": "error" } 
    }); 

Meine Daten sieht etwa so aus:

{ 
    "_id" : "1", 
    "channelStatuses" : [ 
    { 
     "channel" : "FOO", 
     "status" : "done" 
    } 
    ] 
}, 
{ 
    "_id" : "2", 
    "channelStatuses" : [ 
    { 
     "channel" : "BAR", 
     "status" : "done" 
    } 
    ] 
}, 
{ 
    "_id" : "3", 
    "channelStatuses" : [ 
    { 
     "channel" : "BAZ", 
     "status" : "error" 
    } 
    ] 
}, 
{ 
    "_id" : "3", 
    "channelStatuses" : [] 
} 

Also, was ich will es tun, ist, den Status des channelStatuses-Objekt des Dokuments mit _id = 2.

Statt ändern es in der chann ein neues Objekt erstellt elStatuses Array, und das Dokument sieht so aus:

{ 
     "_id" : "2", 
     "channelStatuses" : [ 
     { 
      "channel" : "BAR", 
      "status" : "done" 
     }, 
     { 
      "channel" : "BAR", 
      "status" : "" 
     } 
     ] 
    }, 

Antwort

2

So habe ich einige Probleme mit Ihrer Abfrage gefunden.

  1. Sie in Ihrem Dokument ist _id Feld ein Textwert, aber in Abfrage Sie es als numerisches verwenden.

  2. In Ihrer Abfrage channelStatuses.channel: {$eq: "BAR"} ist ungültig. Der JSON-Schlüssel kann . nicht enthalten, wenn Sie nicht mit doppelten Anführungszeichen entkommen.

  3. Sie können channelStatuses.channel: {$eq: "BAR"} zu "channelStatuses.channel": "BAR"

Jetzt vereinfachen versuchen Abfrage nach und sehen, ob es funktioniert.

var bulk = db.doc.initializeUnorderedBulkOp(); 

bulk.find({ 
    _id: "2", 
    "channelStatuses.channel": "BAR" 
    }).update({ 
      $set: {"channelStatuses.$.status": "error" } 
    }); 

bulk.execute(); 

Es sollte nur bestehende Feld aktualisieren. Siehe Endausgabe unter

{ 
    "_id" : "1", 
    "channelStatuses" : [ 
     { 
      "channel" : "FOO", 
      "status" : "done" 
     } 
    ] 
} 
{ 
    "_id" : "2", 
    "channelStatuses" : [ 
     { 
      "channel" : "BAR", 
      "status" : "error" 
     } 
    ] 
} 
{ 
    "_id" : "3", 
    "channelStatuses" : [ 
     { 
      "channel" : "BAZ", 
      "status" : "error" 
     } 
    ] 
}