我有一个由POJO实现的实体,我们称之为TestEntity
,它保存在Mongo的Collection中。我通过迭代CSV文件并在满足某些条件时插入或更新现有记录来生成此实体的实例。您可以在下面找到我的代码示例
// File is parsed into an entity
MongoClient client = new MongoClient("127.0.0.1", 27017);
Mapper w2sMap = new Mapper();
w2sMap.addMappedClass(TestEntity.class);
morphia = new Morphia();
Datastore datastore = morphia.createDatastore(client, w2sMap, "test");
// SaveTask implements Runnable
@Override
public void run() {
try {
datastore.save(testEntity);
} catch (DuplicateKeyException ex) {
if (updateConditions) // Query Mongo to find the entity, change some fields and save
else // Log
}
SaveTask由ExecutorService由多个线程运行,每个线程保存一个TestEntity实例。然而,一些CSV文件非常庞大,并且必须执行许多save
操作,这很麻烦(在我的机器上大约10分钟内执行750k次保存)。一种解决方案是将TestEntity
存储在Iterable
集合中,然后不时地在集合上发起保存任务,从而减少网络延迟并提高性能(我的实际MongoDB在不同的服务器上运行)< / p>
但是当我尝试使用批量插入时问题会增加,因为当找到重复键时我仍然会遇到异常。我知道new InsertOptions().continueOnError(true)
然而我需要能够一次性插入文档,这将简单地忽略重复的条目。
是否还有这个或者我是否需要捕获异常,找出哪些对象没有保存并继续从那里开始?如果需要,我可以提供更好的代码示例。
答案 0 :(得分:1)
您可以尝试以下几种选择:
datastore.save(testEntity, WriteConcern. UNACKNOWLEDGED);
。这很快但会忽略错误,因为它不会等待服务器确认。 DBCollection coll = db.getCollection("user");
BulkWriteOperation bulk = coll.initializeUnorderedBulkOperation();
bulk.find(new BasicDBObject("z", 1)).upsert().update(new BasicDBObject("$inc", new BasicDBObject("y", -1)));
bulk.find(new BasicDBObject("z", 1)).upsert().update(new BasicDBObject("$inc", new BasicDBObject("y", -1)));
bulk.execute();
您的示例代码并未显示您如何使用upsert,但通常您应该始终捕获异常并自行处理它们。