cyber ice
cyber ice

Reputation: 383

How can I create an autocomplete with MongoDB full text search

I want to create an autocomplete input box that shows word suggestions as users type.

Basically, my problem is that when I use the $text operator for searching strings in a document, the queries will only match on complete stemmed words. This is for the same reason that if a document field contains the word blueberry, a search on the term blue will not match the document. However, a search on either blueberry or blueberries would match.

find = {$text: { $search:  'blue' } };

^ (doesn't match blueberry or bluebird on a document.)

I want to be able to do this. I want to match 'blueberry' or 'bluebird' with 'blue', and initially I thought this was possible by using a 'starts with' (^) regular expression, but it seems like $text and $search only accepts a string; not a regexp.

I would like to know if there is a way to do this that is not excessively complex to implement/maintain. So far, I've only seen people trying to accomplish this by creating a new collection with the results of running a map/reduce across the collection with the text index.

I do not want to use ElasticSearch or Solr because I think it is overkill for what I am trying to do, and although I sometimes think that eventually I will have no other choice, I still cannot believe that there is not a simpler way to accomplish this.

Upvotes: 6

Views: 5829

Answers (2)

amy
amy

Reputation: 36

You can now use Atlas Search natively in MongoDB Atlas to achieve this. You will have to first add the autocomplete field mapping in your index definition before you can use the autocomplete operator to your query. This can be accomplished through the Visual Editor or the JSON editor - there's a tutorial which walks you through how to implement it.

Here's the index definition template from the docs:

{
  "mappings": {
    "dynamic": true|false,
    "fields": {
      "<field-name>": [
        {
          "type": "autocomplete",
          "analyzer": "lucene.standard",
          "tokenization": "edgeGram|rightEdgeGram|nGram",
          "minGrams": <2>,
          "maxGrams": <15>,
          "foldDiacritics": true|false
        }
      ]
    }
  }
}

And the query, where you can also specify support for typo-tolerance via the fuzzy parameter:

{
  $search: {
    "index": "<index name>", // optional, defaults to "default"
    "autocomplete": {
      "query": "<search-string>",
      "path": "<field-to-search>",
      "tokenOrder": "any|sequential",
      "fuzzy": <options>,
      "score": <options>
    }
  }
}

Upvotes: 0

Florian Winter
Florian Winter

Reputation: 5279

MongoDB full text search matches whole words only, so it is inherently not suitable for auto complete.

The $text operator can search for words and phrases. The query matches on the complete stemmed words. For example, if a document field contains the word blueberry, a search on the term blue will not match the document. However, a search on either blueberry or blueberries will match.

(Source: http://docs.mongodb.org/manual/core/index-text/)

Upvotes: 4

Related Questions