如何实现MongoDB全文搜索分页?

时间:2013-04-09 11:54:31

标签: java mongodb

现在我的搜索查询返回了100多个文档,如何为所有返回的文档实现分页?有没有办法用mongoDB实现它,或者我必须获取服务器内存中的所有结果并实现分页(这似乎不合理)。请注意,返回的CommandResult不是DBCursor!

    DBObject searchCommand = new BasicDBObject();
    searchCommand.put("text", collectionName);
    searchCommand.put("search", searchQuery);

    CommandResult commandResult = db.command(searchCommand);

注意:我使用的是Java。

2 个答案:

答案 0 :(得分:7)

text search command没有像MongoDB 2.4那样的skip选项,因此任何分页都必须在您的应用程序代码中实现。

如果您考虑文本搜索的行为(返回根据相关性排名的结果),skip选项仍然必须缓存或计算要跳过的初始结果。

效率

就您的应用程序中的高效分页而言,一些建议是:

  • 缓存初始搜索的结果和切片页面大小的子集,供应用程序呈现
  • 使用客户端插件,它在一个精美的分页视图中显示单个查询的结果(例如使用jQuery DataTables插件)

限制

返回的结果数

文本搜索的默认limit最多返回100个结果。您可以增加限制,但请记住,整个结果文档仍必须符合MongoDB服务器支持的maximum BSON document size(16Mb,与MongoDB 2.4一样)。同样值得考虑的是,大多数用户在搜索结果页面时都有一定的耐心,所以如果你有几百个结果,最好建议改进搜索标准。

其他选项

如果您已经超出了MongoDB 2.4文本搜索的当前限制(顺便提一下,它仍然被认为是“实验性的”),您可以随时升级到功能更全面的搜索产品,例如ElasticSearch或{{ 3}}。有一些方法可以将MongoDB数据更新提供给外部搜索产品,例如使用Apache LuceneElasticSearch River plugin

答案 1 :(得分:3)

对于MongoDB v2.6 +

Spring.IO MongoDB驱动程序最近添加了一个TextCriteria,请参阅$text $search your Documents with Spring Data MongoDB

TextCriteria criteria = TextCriteria.forDefaultLanguage()
  .matchingAny("coffee", "cake");

Query query = TextQuery.queryText(criteria)
  .sortByScore()
  .with(new PageRequest(0, 5));

List<CookingRecipe> recipes = template.find(query, CookingRecipe);

如果您使用Grails MongoDB GORM plug-in,则从3.0.2开始,该API中不提供TextCriteria。

相反,您可以使用mongodb api来执行查询和分页:

// groovy/grails code... java code is very similar
BasicDBObject textSearch = new BasicDBObject('$text', new BasicDBObject('$search', 'cookie'))
BasicDBObject projection = new BasicDBObject('score', new BasicDBObject('$meta', 'textScore'))
BasicDBObject sort = new BasicDBObject('score', new BasicDBObject('$meta', 'textScore'))
DBCursor cursor = CookingRecipe.getCollection().find(textSearch, projection).sort(sort).skip(10).limit(5)