Basic Search Query Types in Elasticsearch

Selin Unal
Nov 3 · 7 min read

Hi everyone 👋

In this post, we will try to understand and explore useful elastic search queries that will help us while using Elasticsearch. In my first Elastic search post, we talked about its basics and how to use kibana and elasticsearch docker containers while learning Elasticsearch which can be found from here:

Let’s start to explore search query types. First of all, we need to run elasticsearch and kibana containers. If you have already installed elasticsearch and kibana into your local device, you can use them instead of docker containers.

Search path of the Elasticsearch

For this post, we will create a ‘companies’ index with ‘company’ document type and we will write search queries and search for a company. I want to show you a company document in detail. A company document will contain the following fields:

  • name: Name of the company
  • found_year: Foundation year of the company
  • avg_salary: Average salary of the company
  • benefits: Benefits of the company that it provides to its employees
  • num_emp: Total number of employees in the company
  • city: The city that the company is located
  • country: The country that the company is located

Using these values we will create search queries and see which companies are listed by Elasticsearch as a result.

Let’s create companies index. From the kibana, (for me it is running on http://localhost:5601/app/kibana) select ‘Dev Tools’ from the left menu and in the console type:

PUT /companies/company

This will create ‘companies’ index with ‘company’ document type stored in 1 shard. You can check whether your index is created successfully or not from the coming message from the Elasticsearch. You need to see:

You can check whether this index is created or not by executing this command:

GET _cat/indices

You need to see companies index in the response listed in the screen:

yellow open companies            IpVICcPZTtSDxls6dRmX8g 1 1      5 0   12kb   12kb

Now, we will insert our company documents into the ‘companies’ index. For this post, we have 5 documents. We will insert documents by using bulk insert property, that is when we have lots of documents with bulk insert we can add documents easily. Just copy the following:

We have 5 companies in total with type ‘company’ under the index ‘companies’.

You can see all your company documents by typing:

GET /companies/company/_search

You will see:

match_all query response

_index,_type, _id, _score, _source fields are metadata fields that are held by Elasticsearch. Under the _source field, we can see all of the company information that we inserted before.

Now we can start to search elastically!

There are two types of searching methods in Elasticsearch. One is Search Lite API which expects search parameters in URL, the other one is Elasticsearch Query DSL (Domain Specific Language) that based on JSON to define queries. We will use Query DSL for this post.

In the following sections, we will cover useful search query types one by one. We will cover basic match query, bool query, fuzzy query, wildcard and regexp queries, match phrase query, term and terms queries and finally range queries.


Basic Match Query

This query allows us to search a word in a specified field or in all of the fields. For example, if we want to search ‘Web Technology’ in the name field we need to execute:

GET /companies/company/_search
{
"query": {"match": {
"name": "Web Technology"}},
"_source": ["name", "brief_info"]
}

We will see:

‘Web’ and ‘Technology’ words are searched in all of the documents’ name field and a match occurs that document is added to the result documents. Additionally, we restrict the result fields by specifying “_source” field in the query.

‘Match’ query is used for searching the word in the specified field. If a match occurs in the field that document is returned back to the user.

If we want to search a word in more than one field we use ‘multi_match’ query which allows searching the word in multiple fields. For example, when we want to search the companies with ‘sport discount’ benefit and in ‘San Francisco’ city, we execute the following command:

GET /companies/company/_search
{
"query": {
"multi_match": {
"query": "San Francisco sport",
"fields": ["city", "benefits"]
}
},
"_source": ["city", "benefits"]
}

This query will search San Francisco and sport words in the fields ‘city’ and ‘benefits’. Whenever a match occurs, that document will be added to the result. Therefore we will see:

If we do not specify the fields in the multi_match query, the desired word will be searched in all of the fields. At the beginning of the indexing, Elasticsearch holds all of the fields under the _all field. _all field is created by concatenating all of the source fields of the document. And Elasticsearch can search the desired word by looking at this _all field. For example, let’s search ‘web technology’ in all fields by using multi_match query type.

GET /companies/company/_search
{
"query": {
"multi_match": {
"query": "web technology"
}
}
}

This query will return the documents that have ‘web’ or ‘technology’ words in any of the fields. We will see:

Bool Query

Bool queries are used to write queries with AND/OR/NOT operators.

In Elasticsearch Query DSL: ‘must’ means AND, ‘should’ means OR and ‘must_not’ means NOT.

For example, if we want to search for companies with benefits ‘sports’ OR ‘rented-house’ and NOT in the cities ‘Ankara’ AND ‘Amsterdam’ we execute the following query:

GET /companies/company/_search 
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"match": {
"benefits": "sport"
}
},
{
"match": {
"benefits": "rented house"
}
}
]
}
}
],
"must_not": [
{
"bool": {

"should": [
{
"match": {
"city": "Ankara"
}
},
{
"match": {
"city": "Amsterdam"
}
}
]
}
}
]
}
}
}

And we will see the following response:

Fuzzy Queries

When searching with match and multi_match queries fuzzy matching can be enabled for the phrases that are spelled incorrectly. For example, when we type ‘developmnt’ instead of ‘development’ with fuzzy queries, results still can be found. In the search query, we need to specify fuzziness value that means how many characters of typos we will allow. If we write 1, it means only 1 character mismatch is allowed, if we type 2, 2 character mismatch is allowed. When we select AUTO, according to word length, distance is calculated accordingly.

Lets search with a fuzzy query:

GET /companies/company/_search
{
"query": {
"multi_match" : {
"query" : "developmnt",
"fields": ["name", "brief_info"],
"fuzziness": "AUTO"
}
},
"_source": ["brief_info", "name"]
}

This query will search misspelled word in the fields name and brief_info. With specifying fuzziness value to AUTO it will find ‘development’ and match. Result documents will be the following:

Wildcard and Regexp Queries

Wildcard queries allow us to search a matching phrase pattern instead of searching full phrases. In wildcard query ? matches any character, * matches zero or more characters.

For example, if we want to search developm* in the brief_info field , we can execute the following query:

GET  /companies/company/_search
{
"query": {
"wildcard" : {
"brief_info": "developm*"
}
},
"_source": ["name", "brief_info"],
"highlight": {
"fields" : {
"brief_info": {}
}
}
}

This query will match any document that has ‘developm*’ in its brief_info filed. Since ‘development’ word fits the phrase we will see following result:

Like wildcard queries, regexp queries also used to search for a pattern that is more complex than wildcard queries. For example, when we want to search the companies in the cities that ends with ‘m’ we execute:

GET /companies/company/_search
{
"query": {
"regexp" : {
"city" : "[a-z]*m"
}
},
"_source": ["name", "city"],
"highlight": {
"fields" : {
"city" : {}
}
}
}

And we see the result:

Match Phrase Query

Match phrase query requires the searched phrase to occur in the same order in the searched field, close to each other. For example, if we search ‘web development’ in the brief_info field we say that ‘web technology’ has to occur exactly in the same order in this field. Let’s show this with an example match phrase query:

GET /companies/company/_search 
{
"query": {
"match_phrase": {
"brief_info":"web technology"
}
},
"_source": ["name", "brief_info"],
"highlight": {
"fields" : {
"brief_info": {}
}
}
}

We will see :

If we type ‘technology web’ results will return empty like below:

Term and Terms Query

Term and terms queries are used to search for exact match in the field. If we want to search for companies that have exact employee number 500, we can use term query like below:

GET /companies/company/_search
{
"query": {
"term": {
"num_emp": {
"value": "500"
}
}
},
"_source": ["name", "num_emp"]
}

Then we will see in the results:

Range Query

Range queries allow us to search for values between the desired range. For example, we can search the companies that are founded after 2010 and before 2015 by executing the following query:

GET /companies/company/_search
{
"query": {
"range" : {
"found_year": {
"gte": "2010-01-01",
"lte": "2015-12-31"
}
}
},
"_source" : ["name","found_year"]
}

Then we will see the companies:


As we can see from the basic Elasticsearch query examples, we can search in a lot of different ways and in a very practical manner. Thank you for reading.

Happy searching 💚

Selin Unal

Written by

Software Engineer @Udemy

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade