Add a field if it does not exist for a document in Mongo

Source Doc

{ 
    "_id" : "12345", 
    "LastName" : "Smith", 
    "FirstName" : "Fred", 
    "ProfileCreated" : NumberLong(1447118831860), 
    "DropOut" : false, 
}

new document

{ 
    "_id" : "12345", 
    "LastName" : "Smith", 
    "FirstName" : "Fred", 
    "ProfileCreated" : NumberLong(1447118831860), 
    "DropOut" : true, 
    "LatestConsultation" : false,
}

I have two collections that contain many identical identifiers and document fields, but over time, new documents will be added to them, and new documents will be created with a new identifier.

I think I know how to process new documents with $setOnInsertand upsert = true, but I'm not sure how best to handle adding new fields. The behavior that I require for documents that exist in a collection that is mapped to _idnew fields is to add a new field to the document without changing the values ​​of any of the other fields, even if they were changed, as in the example where it DropOutchanged. As a result, I need a document.

Results Document

{ 
    "_id" : "12345", 
    "LastName" : "Smith", 
    "FirstName" : "Fred", 
    "ProfileCreated" : NumberLong(1447118831860), 
    "DropOut" : false, 
    "LatestConsultation" : false,
}

? , - , , , , : -)

PS. Pymongo, Pymongo , mongo.

+4
1

, . , :

  • _id . findOne(), , _id .
  • , , .
  • .

mongo :

function merge(from, to) {
    var obj = {};
    if (!from) {
        from = {};
    } else {
        obj = from; 
    }
    for (var key in to) {
        if (!from.hasOwnProperty(key)) {
            obj[key] = to[key];
        }
    }
    return obj;
}

db.new_collection.find({}).snapshot().forEach(function(doc){
    var old_doc = db.old_collection.findOne({ "_id": doc._id }),
        merged_doc = merge(old_doc, doc);

    db.new_collection.update(
        { "_id": doc._id },
        { "$set": merged_doc }
    );
});

, API, , , ( ). - bulkWrite() , :

function merge(from, to) {
    var obj = {};
    if (!from) {
        from = {};
    } else {
        obj = from; 
    }
    for (var key in to) {
        if (!from.hasOwnProperty(key)) {
            obj[key] = to[key];
        }
    }
    return obj;
}

var ops = [];
db.new_collection.find({}).snapshot().forEach(function(doc){
    var old_doc = db.old_collection.findOne({ "_id": doc._id }),
        merged_doc = merge(old_doc, doc);

    ops.push({
        "updateOne": {
            "filter": { "_id": doc._id },
            "update": { "$set": merged_doc }
        }
    });

    if (ops.length === 1000) {
        db.new_collection.bulkWrite(ops);
        ops = [];
    }
});

if (ops.length > 0)  db.new_collection.bulkWrite(ops);

MongoDB 2.6.x 3.0.x Bulk:

var bulk = db.new_collection.initializeUnorderedBulkOp(),
    counter = 0;

db.new_collection.find({}).snapshot().forEach(function(doc){
    var old_doc = db.old_collection.findOne({ "_id": doc._id }),
        merged_doc = merge(old_doc, doc);

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

    if (counter % 1000 === 0) {
        bulk.execute();
        bulk = db.new_collection.initializeUnorderedBulkOp();
    }
});

if (counter % 1000 !== 0 )  bulk.execute();

API- Bulk Operations - , 1000 .

0

Source: https://habr.com/ru/post/1654439/


All Articles