Introducing Query String (query_string) Queries

Madhusudhan Konda
4 min readJan 29, 2023
Excerpts taken from my upcoming book: Elasticsearch in Action

Me @ Medium || LinkedIn || Twitter || GitHub

The query_string type lets us construct a query using operators such as AND or OR, as well as the logical operators such as > (greater than), <= (less than or equal to), * (contains in), and so on. This is easily understood when explained with an example, so let’s jump right in to getting our code ready.

To fetch Bert’s books, we use a request url query like: title:Java and author :Bert and edition:2 and release_date>=2000–01–01. The same is ahieved this by writing a query_string query as the code in the following listing demonstrates.

Listing :  Creating a query string with operator

The query_stringquery expects a query parameter where we provide our criteria. The query is constructed as name-value pairs: for example, in the previous listing, author is the field, and Bert is the value. Looking at the code in that listing, we notice a few things:

  • The search query is built using the Query DSL syntax (the GET request has a body).
  • The search criteria is written to concatenate the fields using operators.

The query is as simple as writing a question in plain English. We can create a complex criteria using these operators (in plain English) and provide it to the engine to get the results for us.

Sometimes, we do not know which fields users are expected to search; they may want the query to focus on the titlefield, or on the synopsisor tagsfields, or all of them. In the next section, we will go over the ways of specifying fields.

Fields in a query string query

In a typical search box, the user does not need to mention the field when searching for something. For example, take a look at the query in the following listing.

GET books/_search
{
"query": {
"query_string": {
"query": "Patterns"
}
},
"highlight": {
"fields": {
"title": {},
"synopsis": {},
"tags": {}
}
}
}

We want to search for the keyword Patterns in the previous query (previous listing). One quick thing to remember is that the query is not asking us to search any fields. It is a generic query that’s actually expected to be executed across all fields. The response (shown in the following snippet) shows that some results were highlighted on a different field for individual documents:

"highlight" : {
"synopsis" : ["Head First Design <em>Patterns</em> is one of ..."],
"title" : ["Head First Design <em>Patterns</em>"]
},
...
"highlight" : {
"synopsis" : [ "create .. using modern application <em>patterns</em>"]
},
...

Instead of letting the engine search query against all the available fields, we can assist Elasticsearch by providing the fields to run the search on. The next listing shows how to do this.

GET books/_search
{
"query": {
"query_string": {
"query": "Patterns",
"fields": ["title","synopsis","tags"]
}
}
}

Here, we specify the fields explicitly in an array in the fieldsparameter and mention the fields that this criteria is expected to be performed against.

If we are not sure of the fields when constructing this query, we can use another parameter, default_fieldas the query in the following listing demonstrates.

GET books/_search
{
"query": {
"query_string": {
"query": "Patterns",
"default_field": "title"
}
}
}

If a field is not mentioned in the query, the search is carried out against the titlefield. That’s because the title field is declared as the default_fieldin the previous listing.

Default operator

In our earlier code example listing, we searched for a single word, Patterns. If we extend that search to include an additional word such as Design, we may get multiple books (two books with the current dataset) instead of the correct one: Head First Design Patterns. The reason is that Elasticsearch uses the OR operator by default when searching. Hence, it finds books with both words, Design OR Patterns in the titlefield.

If this is not our intention (say, for example, we want to fetch a book with the exact phrase Design Patterns in the title), we should use the AND operator. The query_stringquery in the following listing has an additional parameter, default_operator, where we can set the operator to AND.

GET books/_search
{
"query": {
"query_string": {
"query": "Design Patterns",
"default_field": "title",
"default_operator": "AND"
}
}
}

This query_stringquery is declared with the ANDoperator. Hence, you’d expect Design Patterns to be treated as a single word.

Me @ Medium || LinkedIn || Twitter || GitHub

These short articles are condensed excerpts taken from my book Elasticsearch in Action, Second Edition. The code is available in my GitHub repository.

Elasticsearch in Action

--

--

Madhusudhan Konda
Madhusudhan Konda

Written by Madhusudhan Konda

Madhusudhan Konda is a full-stack lead engineer, mentor, and conference speaker. He delivers live online training on Elasticsearch, Elastic Stack &Spring Cloud

No responses yet