Search code examples
elasticsearchfuzzy-searchn-gramelasticsearch-2.0nosql

Fuzzy contains query with elasticSearch


How can I perform a query that do fuzzy and contains on strings? Let's say I have the following document:

{ ... "name":"william shakespeare" ... }

I would like to receive the document for the following queries:

  1. "William" (will return all the williams)
  2. "Willeam" (same as 1)
  3. "William Shake" (will return only the document that contains "William Shake"
  4. "Wiliam sake" (same as 3)
  5. "william shakespeare" / "William Shakespeare" / "William shakespeer" (will return only william shakespeare

I tried to use ngram analyzer and fuzziness queries with no success.

{
  "settings": {
    "analysis": {
      "filter": {
        "ngram_analyzer_filter": {
          "type": "ngram",
          "min_gram": 2,
          "max_gram": 15
        }
      },
      "analyzer": {
        "ngram_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "ngram_analyzer_filter"
          ]
        }
      }
    }
  },
  "mappings": {
    "my_type": {
      "properties": {
        "name": {
          "type": "string",
          "analyzer": "ngram_analyzer",
          "search_analyzer": "standard",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      }
    }
  }
}

my query:

{
  "query": {
    "multi_match": {
      "query": "william shake",
      "fields": [
        "name.raw"
      ],
      "fuzziness": 2,
      "minimum_should_match":2
    }
  }
}
  • It multi_match because I search more than one field.
  • Tried to use the analyzed field or not_analyzed field.
  • Tried to use "type":"phrase"
  • Elastic version 2.3.1

Solution

  • Try below query.

    {
      'query': {
        'multi_match': {
          'fields':  [ 
              "name.raw" 
            ],
            'query': $scope.search.queryTerm,
            'fuzziness': 2,
            'prefix_length': 1
        }
      }
    }