sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB:Kopiera en array till en annan array i samma dokument

För relativt små data kan du uppnå ovanstående genom att iterera insamlingen med en snapshot med markörens forEach() metod och uppdatera varje dokument enligt följande:

db.wholesalers.find({ 
    "brands": { "$exists": true, "$type": 4 } 
}).snapshot().forEach(function(doc){ 
    db.wholesalers.updateOne(
        { "_id": doc._id },
        { "$set": { "brandsNetherlands": doc.brands } }
    );
});

Även om detta är optimalt för små samlingar, reduceras prestandan med stora samlingar avsevärt, eftersom loopning genom en stor datamängd och sändning av varje uppdateringsåtgärd per begäran till servern medför en beräkningsstraff.

Bulk() API kommer till undsättning och förbättrar prestandan avsevärt eftersom skrivoperationer skickas till servern bara en gång i bulk. Effektivitet uppnås eftersom metoden inte skickar varje skrivbegäran till servern (som med den aktuella uppdateringssatsen i forEach() loop) men bara en gång av 1 000 förfrågningar, vilket gör uppdateringar effektivare och snabbare än för närvarande.

Använder samma koncept ovan med forEach() loop för att skapa batcherna kan vi uppdatera samlingen i bulk enligt följande.

I den här demonstrationen visas Bulk() API tillgängligt i MongoDB-versionerna >= 2.6 and < 3.2 använder initializeUnorderedBulkOp() metod för att utföra parallellt, såväl som i en icke-deterministisk ordning, skrivoperationerna i batcherna:

var bulk =db.wholesalers.initializeUorderedBulkOp(),counter =0; // räknare för att hålla reda på batchuppdateringsstorleken

db.wholesalers.find({ 
    "brands": { "$exists": true, "$type": 4 } 
}).snapshot().forEach(function(doc){ 

    bulk.find({ "_id": doc._id }).updateOne({ 
        "$set": { "brandsNetherlands": doc.brands } 
    });

    counter++; // increment counter
    if (counter % 1000 == 0) {
        bulk.execute(); // Execute per 1000 operations and re-initialize every 1000 update statements
        bulk = db.wholesalers.initializeUnorderedBulkOp();
    }
});

Nästa exempel gäller den nya MongoDB-versionen 3.2 som sedan dess har fasat ut Bulk() API och tillhandahöll en nyare uppsättning apis med bulkWrite() .

Den använder samma markörer som ovan men skapar arrayerna med bulkoperationerna med samma forEach() markörmetod för att skicka varje bulkskrivdokument till arrayen. Eftersom skrivkommandon inte kan acceptera fler än 1000 operationer, måste operationer grupperas för att ha högst 1000 operationer och återinitialisera arrayen när loopen träffar 1000 iterationen:

var cursor = db.wholesalers.find({
         "brands": { "$exists": true, "$type": 4 } 
    }),
    bulkUpdateOps = [];

cursor.snapshot().forEach(function(doc){ 
    bulkUpdateOps.push({ 
        "updateOne": {
            "filter": { "_id": doc._id },
            "update": { "$set": { "brandsNetherlands": doc.brands } }
         }
    });

    if (bulkUpdateOps.length === 1000) {
        db.wholesalers.bulkWrite(bulkUpdateOps);
        bulkUpdateOps = [];
    }
});         

if (bulkUpdateOps.length > 0) { db.wholesalers.bulkWrite(bulkUpdateOps); }



  1. CastError:Cast to ObjectId misslyckades för värdet ruttnamn vid sökvägen _id för modellen

  2. Hur får man tillbaka uppdaterat dokument från metoden findOneAndUpdate?

  3. konvertera från blob till binär för att spara den till mongodb

  4. Hur man hittar om det finns en punkt i vilken polygon