sql >> Database >  >> NoSQL >> MongoDB

MongoDB:een array kopiëren naar een andere array in hetzelfde document

Voor relatief kleine gegevens kunt u het bovenstaande bereiken door de verzameling te herhalen met een snapshot met de forEach() van de cursor methode en update elk document als volgt:

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

Hoewel dit optimaal is voor kleine verzamelingen, worden de prestaties bij grote verzamelingen sterk verminderd, aangezien het doorlopen van een grote dataset en het verzenden van elke updatebewerking per verzoek naar de server een rekenfout met zich meebrengt.

De Bulk() API komt te hulp en verbetert de prestaties aanzienlijk, omdat schrijfbewerkingen slechts één keer in bulk naar de server worden verzonden. Efficiëntie wordt bereikt omdat de methode niet elk schrijfverzoek naar de server stuurt (zoals bij de huidige update-instructie in de forEach() loop) maar slechts één keer op elke 1000 verzoeken, waardoor updates efficiënter en sneller zijn dan nu het geval is.

Gebruik hetzelfde concept hierboven met de forEach() loop om de batches te maken, kunnen we de verzameling als volgt in bulk bijwerken.

In deze demonstratie wordt de Bulk() API beschikbaar in MongoDB-versies >= 2.6 and < 3.2 gebruikt de initializeUnorderedBulkOp() methode om de schrijfbewerkingen in de batches parallel en in een niet-deterministische volgorde uit te voeren:

var bulk =db.wholesalers.initializeUnorderedBulkOp(),counter =0; // teller om de grootte van de batchupdate bij te houden

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();
    }
});

Het volgende voorbeeld is van toepassing op de nieuwe MongoDB-versie 3.2 die sindsdien de Bulk() heeft afgeschaft API en leverde een nieuwere set api's met behulp van bulkWrite() .

Het gebruikt dezelfde cursors als hierboven, maar maakt de arrays met de bulkbewerkingen met dezelfde forEach() cursor-methode om elk bulkschrijfdocument naar de array te pushen. Omdat schrijfopdrachten niet meer dan 1000 bewerkingen kunnen accepteren, is het nodig om bewerkingen te groeperen om maximaal 1000 bewerkingen te hebben en de array opnieuw te initialiseren wanneer de lus de 1000-iteratie bereikt:

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. MongoDB opvragen vanuit de browser met behulp van een flask-backend

  2. Hoe u het beste een RESTful API kunt maken in Node.js

  3. Spring Data Redis Expire Key

  4. mongodb-array-overeenkomst