我得到了大约300,000个条目的数据集。为了存储该数据,我正在使用当前版本的mongodb 2.2.3。我的问题是如何通过使用聚合框架来提高搜索性能?
这是我存储数据的一个示例:
{
"_id":"654311649875645643131564",
"@type":"K",
"dataSourceA":{
"name": "abc",
"price": 12.99
},
"dataSourceB":{
"name": "xyz"
}
}
在我切换到较新版本的mongodb之前,我处理了例如没有聚合框架的最大值如下:
searchQuery = new BasicDBObject("dataSourceA.price", -1);
DBCursor cursor = collection.find().sort(searchQuery).limit(1);
此操作大约需要0.921 secs
现在我尝试使用聚合框架来实现相同的结果,但希望更快地找到最高价格。这是我的方法:
DBObject match = new BasicDBObject("$match", new BasicDBObject("@type", "K"));
DBObject fields = new BasicDBObject("dataSourceA.price", 1);
DBObject project = new BasicDBObject("$project", fields);
DBObject groupFields = new BasicDBObject("_id", 1);
groupFields.put("max", new BasicDBObject("$max", "$dataSourceA.price"));
DBObject group = new BasicDBObject("$group", groupFields);
Iterable<DBObject> results =
collection.aggregate(match, project, group).results();
但是此操作需要大约4.837 secs
才能找到最高价格。那么我的查询可以改进什么呢?我认为像这样的数据库应该比在java中迭代游标更快,在我错的时候纠正我。
答案 0 :(得分:1)
这有很多原因。
首先,对于光标示例,您只是运行一个查询,对子文档字段上的所有根文档进行排序,很可能是索引的。无论你怎么看,它都会更快。
第二个$max
实际上是一个$group
运算符,这意味着它是适合您的查询集的所有文档的内存操作(全部300,000个),因此MongoDB正在计算对于结果集中的所有文档,每个文档的多值字段的最大值(在_id
上分组)。
由于$max
的工作方式,您立即失去了从索引光标中获得的即时排序功能。
不仅如此,您还在聚合中途进行预测,使MongoDB进一步有力地分割您的文档。
所以不,它不应该比迭代已排序的索引游标更快。