我们正在使用MongoDb
来保存和获取数据。
将数据放入集合的所有调用都运行正常,并且通过常用方法。
从集合中获取数据的所有调用有时都能正常工作,并且通过常用方法。
但有时候,只针对其中一个,我会让我的电话永久停滞,消耗CPU使用率。我必须手动杀死线程,否则它会消耗我的整个CPU。
Mongo Connection
MongoClient mongo = new MongoClient(hostName , Integer.valueOf(port));
DB mongoDb = mongo.getDB(dbName);
要提取的代码
DBCollection collection = mongoDb.getCollection(collectionName);
DBObject dbObject = new BasicDBObject("_id" , key);
DBCursor cursor = collection.find(dbObject);
虽然我已经找到了它导致问题的集合,但是我怎样才能改进这一点,因为它发生在这个特定的集合中,有时候。
修改
保存代码
DBCollection collection = mongoDb.getCollection(collectionName);
DBObject query = new BasicDBObject("_id" , key);
DBObject update = new BasicDBObject();
update.put("$set" , JSON.parse(value));
collection.update(query , update , true , false);
批量撰写/收藏
DB mongoDb = controllerFactory.getMongoDB();
DBCollection collection = mongoDb.getCollection(collectionName);
BulkWriteOperation bulkWriteOperation = collection.initializeUnorderedBulkOperation();
Map<String, Object> dataMap = (Map<String, Object>) JSON.parse(value);
for (Entry<String, Object> entrySet : dataMap.entrySet()) {
BulkWriteRequestBuilder bulkWriteRequestBuilder = bulkWriteOperation.find(new BasicDBObject("_id" ,
entrySet.getKey()));
DBObject update = new BasicDBObject();
update.put("$set" , entrySet.getValue());
bulkWriteRequestBuilder.upsert().update(update);
}
如何为fetch调用设置超时.. ??
答案 0 :(得分:1)
只是一些可能的解释/想法
一般&#34;按id&#34;查询必须要快,因为_id应该被索引。总是。 代码片段看起来是正确的,所以可能原因在于mongo本身。 这引出了一些建议:
尝试直接从命令行连接到mongo并运行&#34; find&#34;从那里。很有可能你仍然能够偶尔看到缓慢的情况。
在这种情况下:
也许是关于磁盘的(也许这个特定的服务器部署在慢速磁盘上,或者至少存在与访问磁盘有些缓慢的关联)。
也许你的配置是分片的,一个分片比其他分片慢
可能是零星发生的网络问题。如果你在本地/在staging env上运行mongo。与此相同的集合是否会重现?
也许(虽然我几乎不相信),但查询以次优的方式运行。在这种情况下,您可以使用&#34; explain()&#34;正如有人已经在这里建议的那样。
如果您碰巧有副本集,请弄清楚[Read Preference]是什么。谁知道,也许您更喜欢从次优服务器获取此ID
我可能错过了一些东西,但这些应该是好方向,我相信
希望,这有帮助
答案 1 :(得分:1)
另一种方法是使用MongoDB 3.2 Driver提出的方法。请注意,您必须将.jar库(如果您还没有)更新到最新版本。
public final MongoClient connectToClient(String hostName, String port) {
try {
MongoClient client = new MongoClient(hostName, Integer.valueOf(port));
return client;
} catch(MongoClientException e) {
System.err.println("Cannot connect to Client.");
return null;
}
}
public final MongoDatabase connectToDB(String databaseName) {
try {
MongoDatabase db = client.getDatabase(databaseName);
return db;
} catch(Exception e) {
System.err.println("Error in connecting to database " + databaseName);
return null;
}
public final void closeConnection(MongoClient client) {
client.close();
}
public final void findDoc(MongoDatabase db, String collectionName) {
MongoCollection<Document> collection = db.getCollection(collectionName);
try {
FindIterable<Document> iterable = collection
.find(new Document("_id", key));
Document doc = iterable.first();
//For an Int64 field named 'special_id'
long specialId = doc.getLong("special_id");
} catch(MongoException e) {
System.err.println("Error in retrieving document.");
} catch(NullPointerException e) {
System.err.println("Document with _id " + key + " does not exist.");
}
}
public final void insertToDB(MongoDatabase db, String collectioName) {
try {
db.getCollection(collectionName).insertOne(new Document()
.append("special_id", 5)
//Append anything
);
catch(MongoException e) {
System.err.println("Error in inserting new document.");
}
}
public final void updateDoc(MongoDatabase db, String collectionName, long id) {
MongoCollection<Document> collection = db.getCollection(collectionName);
try {
collection.updateOne(new Document("_id", id),
new Document("$set",
new Document("special_id",
7)));
catch(MongoException e) {
System.err.println("Error in updating new document.");
}
}
public static void main(String[] args) {
String hostName = "myHost";
String port = "myPort";
String databaseName = "myDB";
String collectionName = "myCollection";
MongoClient client = connectToClient(hostName, port);
if(client != null) {
MongoDatabase db = connectToDB(databaseName);
if(db != null) {
findDoc(db, collectionName);
}
client.closeConnection();
}
}
编辑:正如其他人建议的那样,从命令行检查是否通过其ID查找文档的过程也很慢。那么这可能是你的硬盘问题。 _id
应该被编入索引,但无论好坏,都要在_id
字段上重新创建索引。
答案 2 :(得分:0)
其他人发布的答案很棒,但并没有解决我的目的。
实际上问题在于我现有的代码本身,我的cursor
正在等待循环无限时间。
我错过了几张现已解决的支票。