简体   繁体   中英

Why are upserts so slow for MongoDB Java API?

Using Mongo Java Driver 2.13 and Mongo 3.0.

I am trying to move from Spring Data save() to MongoDB API's Bulk Writing since I am saving/updating about 100K objects. I am trying to write the Service/Repository layer code where I can pass in a Collection of my specific Objects and be able to either create new records or update existing records, or in other words upsert. When I do an insert the performance is very acceptable.

If I update the code to do upserts the performance is just way too slow. Am I doing something wrong in the following code sample (note it is scaled down to just the necessary logic, ie no error handling):

public void save(Collection<MyDomainObject> objects) {
    BulkWriteOperation bulkWriter = dbCollection.initializeUnorderedBulkOperation();
    for(MyDomainObject mdo : objects) {
        DBObject dbObject = convert(mdo);
        bulkWriter.find(new BasicDBObject("id",mdo.getId()))
           .upsert().updateOne(new BasicDBObject("$set",dbObject));
    }
    bulkWriter.execute(writeConcern);
}

Note that I also tried replaceOne() instead of updateOne() with the same results.

I also noticed in the Mongo log that "nscannedObjects" keeps increasing while "nMatched", "nModified" and "upsert" are never larger than 1. Does this mean that it is table scanning for each record?

Am I using upsert the correct way? Any other suggestions?

Thanks to ry_donahue I figured out the issue.

It was not using the correct ID field, which is the index. In the conversion of the domain object to a DBObject there ended up being an "id" and an "_id" field.

I also changed updateOne() to replaceOne(). So now the code looks like this:

 public void save(Collection<MyDomainObject> objects) {
     BulkWriteOperation bulkWriter = dbCollection.initializeUnorderedBulkOperation();
    for(MyDomainObject mdo : objects) {
        DBObject dbObject = convert(mdo);
        bulkWriter.find(new BasicDBObject("_id",new ObjectId(mdo.getId()))).upsert().replaceOne(dbObject);
     }
     bulkWriter.execute(writeConcern);
 }   

This now gives very good performance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM