ElasticSearch - Using FilterBuilders

aces. picture aces. · May 10, 2013 · Viewed 19.9k times · Source

I am new to ElasticSearch and Couchbase. I am building a sample Java application to learn more about ElasticSearch and Couchbase.

Reading the ElasticSearch Java API, Filters are better used in cases where sort on score is not necessary and for caching. I still haven't figured out how to use FilterBuilders and have following questions:

  • Can FilterBuilders be used alone to search?
  • Or Do they always have to be used with a Query? ( If true, can someone please list an example? )
  • Going through a documentation, if I want to perform a search based on field values and want to use FilterBuilders, how can I accomplish that? (using AndFilterBuilder or TermFilterBuilder or InFilterBuilder? I am not clear about the differences between them.)

For the 3rd question, I actually tested it with search using queries and using filters as shown below. I got empty result (no rows) when I tried search using FilterBuilders. I am not sure what am I doing wrong.

Any examples will be helpful. I have had a tough time going through documentation which I found sparse and even searching led to various unreliable user forums.

private void processQuery() {
        SearchRequestBuilder srb = getSearchRequestBuilder(BUCKET);
        QueryBuilder qb = QueryBuilders.fieldQuery("doc.address.state", "TX");
        srb.setQuery(qb);

        SearchResponse resp = srb.execute().actionGet();
        System.out.println("response :" + resp);
    }

private void searchWithFilters(){
        SearchRequestBuilder srb = getSearchRequestBuilder(BUCKET);
        srb.setFilter(FilterBuilders.termFilter("doc.address.state", "tx"));
        //AndFilterBuilder andFb = FilterBuilders.andFilter();
        //andFb.add(FilterBuilders.termFilter("doc.address.state", "TX")); 
        //srb.setFilter(andFb);
        SearchResponse resp = srb.execute().actionGet();
        System.out.println("response :" + resp);
    }

--UPDATE--

As suggested in the answer, changing to lowercase "tx" works. With this question resolved. I still have following questions:

  • In what scenario(s), are filters used with query? What purpose will this serve?
  • Difference between InFilter, TermFilter and MatchAllFilter. Any illustration will help.

Answer

javanna picture javanna · May 10, 2013

Right, you should use filters to exclude documents from being even considered when executing the query. Filters are faster since they don't involve any scoring, and cacheable as well.

That said, it's pretty obvious that you have to use a filter with the search api, which does execute a query and accepts an optional filter. If you only have a filter you can just use the match_all query together with your filter. A filter can be a simple one, or a compund one in order to combine multiple filters together.

Regarding the Java API, the names used are the names of the filters available, no big difference. Have a look at this search example for instance. In your code I don't see where you do setFilter on your SearchRequestBuilder object. You don't seem to need the and filter either, since you are using a single filter. Furthermore, it might be that you are indexing using the default mappings, thus the term "TX" is lowercased. That's why when you search using the term filter you don't find any match. Try searching for "tx" lowercased.

You can either change your mapping if you want to keep the "TX" term as it is while indexing, probably setting the field as not_analyzed if it should only be a single token. Otherwise you can change filter, you might want to have a look at a query that is analyzed, so that your query wil be analyzed the same way the content was indexed.

Have a look at the query DSL documentation for more information regarding queries and filters:

  • MatchAllFilter: matches all your document, not that useful I'd say
  • TermFilter: Filters documents that have fields that contain a term (not analyzed)
  • AndFilter: compound filter used to put in and two or more filters

Don't know what you mean by InFilterBuilder, couldn't find any filter with this name.

The query usually contains what the user types in through the text search box. Filters are more way to refine the search, for example clicking on facet entries. That's why you would still have the query plus one or more filters.