sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB uppdaterar alla fält med arrayfel

REDIGERA

Detaljen som saknades i frågan var att det obligatoriska fältet att uppdatera faktiskt fanns i ett underdokument . Detta ändrar svaret avsevärt:

Detta är en begränsning av vad du kan möjligen göra med att uppdatera arrayelement. Och detta förklaras tydligt i dokumentationen . Mest i det här stycket:

Så här är grejen. Försöker uppdatera alla av arrayelementen i en enstaka sats som denna inte arbete. För att göra detta måste du göra följande.

db.warehouses.find({ "items.qty": { "$gt": 0 } }).forEach(function(doc) {
    doc.items.forEach(function(item) {
        item.qty = 0;
    });
    db.warehouses.update({ "_id": doc._id }, doc );
})

Vilket i princip är sättet att uppdatera varje arrayelement.

multi inställning i .update() betyder över flera "dokument". Det kan inte tillämpas på flera element i en array. Så för närvarande är det bästa alternativet att byta ut det hela. Eller i det här fallet kan vi lika gärna byta ut hela dokument eftersom vi måste göra det ändå.

För riktigt massdata, använd db.eval() . Men läs dokumentationen först:

db.eval(function() {
    db.warehouses.find({ "items.qty": { "$gt": 0 } }).forEach(function(doc) {
        doc.items.forEach(function(item) {
            item.qty = 0;
        });
        db.warehouses.update({ "_id": doc._id }, doc );
    });
})

Uppdaterar alla elementen i en array tvärs över helheten samlingen är inte enkel.

Original

Ungefär exakt vad felet säger. För att kunna använda en positionsoperator måste du matcha något först. Som i:

db.warehouses.update(
    // query 
    {
        _id:ObjectId('5322f07e139cdd7e31178b78'),
        "items.qty": { "$gt": 0 }
    },    
    // update 
    {
        $set:{"items.$.qty":0}
    },    
    // options 
    {
        "multi" : true,  
        "upsert" : true  
    }
);

Så där matchen skick fenor positionen av objekten som är mindre än 0 sedan det indexet skickas till positionsoperatören.

P.S :När muti är sant det betyder att den uppdateras varje dokumentera. Lämna det false om du bara menar en . Vilket är standard.



  1. hur man använder $project return nest array efter $lookup i mongodb

  2. MongoError:ns hittas inte när du försöker avbryta samlingen

  3. MongoDB Database, motsvarande för SELECT kolumn1, kolumn2 FRÅN tbl

  4. Mongoose - Effektiv uppdatering av en indexerad array av mongoose.Schema.Types.Mixed