7

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

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

    CommandResult commandResult = db.command(searchCommand);

注意:我使用的是 Java。

4

2 回答 2

7

text搜索命令没有 MongoDB 2.4 中的选项skip,因此任何分页都必须在您的应用程序代码中实现。

如果您考虑文本搜索的行为(即返回基于相关性排名的结果),一个skip选项仍然需要缓存或计算要跳过的初始结果。

效率

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

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

限制返回的结果数

文本搜索的默认设置limit是最多返回 100 个结果。您可以增加限制,但请记住,整个结果文档仍必须符合您的 MongoDB 服务器支持的最大 BSON 文档大小(16Mb,如 MongoDB 2.4)。还值得考虑的是,大多数用户在搜索结果页面时的耐心有限,因此如果您有几百个结果,建议改进搜索条件可能会更好。

其他选项

如果您已经超出了 MongoDB 2.4 文本搜索的当前限制(顺便说一句,它仍然被认为是“实验性的”),您可以随时升级到功能更全的搜索产品,例如ElasticSearchApache Lucene。有多种方法可以将 MongoDB 数据更新输入外部搜索产品,例如使用ElasticSearch River 插件Mongo 连接器

于 2013-04-09T14:49:14.037 回答
4

对于 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 插件,则从 3.0.2 开始,TextCriteria 在该 API 中不可用。

相反,您可以使用 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)
于 2014-10-23T19:48:38.000 回答