Adelin
Adelin

Reputation: 18951

How to implement MongoDB full text search pagination?

Now that my search query returns more than 100 documents, How do I implement pagination for all returned documents ? Is there A way to implement it withing mongoDB or I have to fetch all results in the server memory and implement pagination ( which does not seems reasonable ). Note that CommandResult is returned not a DBCursor !

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

    CommandResult commandResult = db.command(searchCommand);

Note: I am using Java.

Upvotes: 7

Views: 5188

Answers (2)

GregHouston
GregHouston

Reputation: 41

For MongoDB v2.6+

Spring.IO MongoDB driver has recently added a TextCriteria, see $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);

If you are using Grails MongoDB GORM plug-in, as of 3.0.2 the TextCriteria is not available in that API.

Instead you can use the mongodb api to perform the query and paginate:

// 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)

Upvotes: 4

Stennie
Stennie

Reputation: 65313

The text search command does not have a skip option as at MongoDB 2.4, so any pagination will have to be implemented in your application code.

If you consider the behaviour of text search (which is to return results ranked based on relevance), a skip option would still have to cache or calculate the initial results to skip.

Efficiency

As far as efficient pagination in your application, a few suggestions would be:

  • cache the results of the initial search and slice page-sized subsets for your application to render
  • use a client-side plugin which presents the results from a single query in a nicely paginated view (for example using the jQuery DataTables plugin)

Number of results returned by limit

The default limit for text search is to return a maximum of 100 results. You can increase the limit, but keep in mind that the overall result document must still fit within the maximum BSON document size supported by your MongoDB server (16Mb, as at MongoDB 2.4). It's also worth considering that most users have a finite patience in searching through pages of results, so if you have a few hundred results it may better to suggest refining the search criteria.

Other options

If you have outgrown the current limitations of MongoDB 2.4's text search (which, incidentally, is still considered "experimental") you can always upgrade to a more full featured search product such as ElasticSearch or Apache Lucene. There are ways to feed your MongoDB data updates into external search products such as using an ElasticSearch River plugin or the Mongo Connector.

Upvotes: 7

Related Questions