Creating a query

Before search, a query must be built: ElasticSearch provides several ways to build these queries. In this recipe, will see how to create a query object via QueryBuilder and via simple strings.

Getting ready

You need a working ElasticSearch cluster and a working copy of Maven. The code of this recipe is in chapter_10/nativeclient in the code bundle of this book available on Packt's website and the referred class is QueryCreation.

How to do it...

For creating a query, we will perform the steps given as follows:

  1. There are several ways to define a query in ElasticSearch; they are interoperable.

    Generally a query can be defined as a:

    • QueryBuilder: This is a helper to build a query.
    • XContentBuilder: This is a helper to create JSON code. We discussed it in the Managing mapping recipe in this chapter. The JSON code to be generated is similar to the previous REST, but converted in programmatic code.
    • Array of bytes or string: In this case, it's usually the JSON to be executed as we have seen in REST calls.
    • Map: This contains query and value of the query.
  2. We'll create a query using QueryBuilder and execute a search (the search via native API will be discussed in the next recipes):
    ….
    import org.elasticsearch.common.xcontent.XContentFactory;
    import org.elasticsearch.index.query.BoolQueryBuilder;
    import org.elasticsearch.index.query.QueryBuilder;
    import org.elasticsearch.index.query.RangeQueryBuilder;
    import org.elasticsearch.index.query.TermFilterBuilder;
    
    import java.io.IOException;
    import static org.elasticsearch.index.query.QueryBuilders.*;
    import static org.elasticsearch.index.query.FilterBuilders.*;
    
    public class QueryCreation {
    
      public static void main( String[] args )
      {
        String index="mytest";
        …
    
        BulkRequestBuilder bulker=client.prepareBulk();
        for (Integer i=1; i<1000; i++){
          bulker.add(client.prepareIndex(index, type, i.toString()).setSource("text", i.toString(), "number1", i+1, "number2", i%2));
        }
        bulker.execute().actionGet();
    
        client.admin().indices().prepareRefresh(index). execute().actionGet();
    
        TermFilterBuilder filter = termFilter("number2", 1);
        RangeQueryBuilder range = rangeQuery("number1").gt(500);
        BoolQueryBuilder bool = boolQuery().must(range);
    
        QueryBuilder query = filteredQuery(bool, filter);
    
        SearchResponse response=client.prepareSearch(index).setTypes(type).setQuery(query).execute().actionGet();
        System.out.println("Matched records of elements: " + response.getHits().getTotalHits());
    
        io.deleteIndex(index);    }
    }

    I removed the redundant parts that are similar to the example of the previous recipe.

  3. The result will be:
    Matched records of elements: 250

How it works...

In the previous example, we have created a query via QueryBuilder. The first step is to import the query builder from the namespace:

import static org.elasticsearch.index.query.QueryBuilders.*;

Because we need the field builders, we also need to import them:

import static org.elasticsearch.index.query.FilterBuilders.*;

The query of the example is a filtered query composed of a Boolean query and a term filter. The goal of the example is to show how to mix several query/filter types for creating a complex query.

The Boolean query contains a must clause with a range query. We start to create the range query:

RangeQueryBuilder range = rangeQuery("number1").gte(500);

This range query matches, in the "number1" field, all the values bigger than ("gte") 500. After having created the range query, we can add it to a Boolean query in the must block:

BoolQueryBuilder bool = boolQuery().must(range);

In real-world complex queries, you can have a lot of nested queries in a Boolean query or filter.

To build our filtered query, we need to define a filter. In this case, we have used a term filter, which is one of the most used:

   TermFilterBuilder filter = termFilter("number2", 1);

The termFilter instance accepts a field and a value, which must be a valid ElasticSearch type. The previous code is similar to the JSON REST {"term": {"number2":1}.

Now, we can build the final filtered query that we can execute in the search:

QueryBuilder query = filteredQuery(bool, filter);

Tip

Before executing a query and to be sure not to miss any results, the index must be refreshed. In the example, it's done with client.admin().indices().prepareRefresh(index).execute().actionGet();.

There's more...

The possible native queries/filters are same as the REST ones and have the same parameters: the only difference is that they are exposed via builder methods.

The most common query builders are:

  • matchAllQuery: This allows matching all the documents.
  • matchQuery and matchPhraseQuery: This is used to match against the text string.
  • termQuery and termsQuery: This is used to match a value/s.
  • boolQuery: This is used to aggregate other queries.
  • idsQuery: This is used to match a list of IDs.
  • fieldQuery: This is used to match a field with a text.
  • wildcardQuery: This is used to match terms with wildcards (*?.).
  • regexpQuery: This is used to match terms via a regular expression.
  • spanTermsQuery, spanTermQuery, spanORQuery, spanNotQuery, spanFirstQuery, span, and so on: These are a few examples from the span query family. These are used in building span query.
  • filteredQuery: In this, the query is composed of a query and a filter.
  • constantScoreQuery: This accepts a query or a filter and all the matched documents are set with the same score.
  • moreLikeThisQuery and fuzzyLikeThisQuery: These are used to retrieve similar documents.
  • hasChildQuery, hasParentQuery, and nestedQuery: These are used in manage related documents.

The previous list is not complete, because it is evolving during the life of ElasticSearch. New query types are added to cover new search cases or they are seldom renamed, such as text query in match query.

Similar to the query builders, there are a lot of query filters:

  • matchAllFilter: This matches all the documents
  • termFilter and termsFilter: These are used to filter a given value/s
  • idsFilter: This is used to filter a list of IDs
  • typeFilter: This is used to filter all the documents of a type
  • andFilter, orFilter, and notFilter: These are used to build Boolean filters
  • wildcardFilter: This is used to filter terms with wildcards (*?.)
  • regexpFilter: This is used to filter terms via a regular expression
  • rangeFilter: This is used to filter using a range
  • scriptFilter: This is used to filter documents using the scripting engine
  • geoDistanceFilter, geoBoundingBoxFilter, and other geo filter: These provide geo filtering of documents
  • boolFilter: This is used to create a Boolean filter which aggregates other filters

See also

  • Query/filter-related recipes in Chapter 5, Search, Queries, and Filters
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.112.7