26

I am little bit confused while creating Filtered query in Elasticsearch Java API. SearchRequestBuilder class has setPostFilter method, javadoc of this method clearly says that filter will be applied after Query is executed.

However, there is no setFilter method Or some other method which will allow to apply filter before
query is executed. How do I create filtered Query(which basically applies filter before query is executed) here? Am I missing something?

5 Answers 5

31
 FilteredQueryBuilder builder = 
 QueryBuilders.filteredQuery(QueryBuilders.termQuery("test", 
 "test"),FilterBuilders.termFilter("test","test"));

It will build the filtered query...To filteredQuery, first argument is query and second arguments is Filter.

Update: Filtered query is depreciated in elasticsearch 2.0+.refer

Hope it helps..!

Sign up to request clarification or add additional context in comments.

1 Comment

things have changed in API v. 2.0 and later. See my answer.
13

QueryBuilders.filteredQuery is deprecated in API v. 2.0.0 and later.

Instead, filters and queries have "equal rights". FilterBuilders no longer exists and all filters are built using QueryBuilders.

To implement the query with filter only (in this case, geo filter), you would now do:

QueryBuilder query = QueryBuilders.geoDistanceQuery("location")
        .point(center.getLatitude(), center.getLongitude())
        .distance(radius, DistanceUnit.METERS);

// and then...
SearchResponse resp = client.prepareSearch(index).setQuery(query);

If you want to query by two terms, you would need to use boolQuery with must:

QueryBuilder query = QueryBuilders.boolQuery()
            .must(QueryBuilders.termQuery("user", "ben"))
            .must(QueryBuilders.termQuery("rank", "mega"));

// and then...
SearchResponse resp = client.prepareSearch(index).setQuery(query);

3 Comments

according to the documentation there is a difference between a query and filter contexts, namely filtering is without scoring of matches and might perform better. Daphna, when using the API as suggested, can this achieved differentiation be achieved, or is scoring implictly calculated (thus potentially taking away from performance)?
@YonatanWilkof That's a great question. You should ask it as a main question rather than in the comments thread, somebody might be able to help you.
It seems that by wrapping the query (a BoolQueryBuilder object) by giving it as an argument to boolQuery().filter(..) and then setting that in the setQuery() as you suggested- then this can be achieved. The "score" key in the response is always 0 (though documents are found)
8

In case you just want to execute filter without query, you can do like this:

FilteredQueryBuilder builder = QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(),
   FilterBuilders.termFilter("username","stackoverflow"));

Ref: Filtering without a query

Comments

1

It seems that by wrapping the query (a BoolQueryBuilder object) by giving it as an argument to boolQuery().filter(..) and then setting that in the setQuery() as you suggested- then this can be achieved. The "score" key in the response is always 0 (though documents are found)

Be careful here! If the score is 0, the score has been calculated. That means the query is still in query context and not in filter context. In filter context the score is set to 1.0 (without calculation) source

To create a query in filter context without calculation of the score (score = 1.0) do the following (Maybe there is still a better way?):

QueryBuilder qb = QueryBuilders.constantScoreQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("name", "blub)));

This returns the same results like:

GET /indexName/typeName/_search 
    {
      "filter": {
        "query": {
          "bool": {
            "must": [
              { "match": {
                "name": "blub"
              }}
            ]
          }
        }
      }
    }

1 Comment

Filter is used with bool. Please refer this doc elastic.co/guide/en/elasticsearch/reference/current/… Constant Query wraps a filter query and returns every matching document with a relevance score equal to the 'boost parameter value' elastic.co/guide/en/elasticsearch/reference/7.17/…
1

Since FilteredQueryBuilder is deprecated in the recent versions, one can use the QueryBuilders.boolQuery() instead, with a must clause for the query and a filter clause for the filter.

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

QueryBuilder builder = boolQuery().must(termQuery("test", "test")).filter(  boolQuery().must(termQuery("test", "test")));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.