Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Contains Query or Partial matching in Elasticsearch

I'm looking to search a word say "amend" which may be present in data as "amending", "amendment" or even "*amend". Which is the best method to search words like these? I know wildcard can achieve this but I am restricted to not using it due to my other part of the code. What are the different ways which provides better search performance?

like image 281
Nikesh Manjunath Avatar asked Sep 27 '18 07:09

Nikesh Manjunath


People also ask

What is the difference between match and term query in Elasticsearch?

To better search text fields, the match query also analyzes your provided search term before performing a search. This means the match query can search text fields for analyzed tokens rather than an exact term. The term query does not analyze the search term. The term query only searches for the exact term you provide.

What is partial match search?

The partial match feature allows the index to return items that only contain a subset of the keywords entered by the end user. 1. This ensures that relevant items which only contain some of the query keywords are returned, and reduces the chance of receiving no results in the response.

What kind of queries does Elasticsearch support?

Elasticsearch provides a full Query DSL (Domain Specific Language) based on JSON to define queries. Think of the Query DSL as an AST (Abstract Syntax Tree) of queries, consisting of two types of clauses: Leaf query clauses.

What is Elasticsearch matching?

The match query is of type boolean . It means that the text provided is analyzed and the analysis process constructs a boolean query from the provided text. The operator parameter can be set to or or and to control the boolean clauses (defaults to or ).


2 Answers

You can implement this using query_string feature of elasticsearch. Assuming that you use default standard analyzer.

{  
   "query":{  
      "query_string":{  
         "default_field":"Customer",
         "query":"*Jo*"
      }
   }
} 

You can add multiple fields as well as shown in the below query

{  
   "query":{  
      "query_string":{  
         "fields":[  
            "Customer",
            "Name"
         ],
         "query":"*Jo*"
      }
   }
}
like image 105
Kamal Avatar answered Oct 11 '22 13:10

Kamal


There is various way:

As you mention you cannot use wildcard, Then go for query_string

{  
   "query":{  
      "query_string":{  
         "default_field":"text",
         "query":"*amend"
      }
   }
}

Second you can use n-gram tokenizer. You can check here https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-ngram-tokenizer.html

It will breaks your value "amending" to words like ["ame","men","end" ... etc]

Once you done with applying n-gram tokeinzer, Start indexing your data.

You can query like below:

{"query":{"term":{"text":"amend"}}}

You will get your output result.

like image 24
Ashish Tiwari Avatar answered Oct 11 '22 12:10

Ashish Tiwari