Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

elasticsearch QueryBuilder with dynamic list value in term query

I have a code like below where I'm doing multiple must in bool query. Here I'm passing the must term queries in field "address". Now the ip address will come to me as a list from other api and I have to pass for all the ip's in the list as a must term query. Here I'm not getting a way how to pass the address values dynamically when creating the QueryBuilder.

Please suggest how to do this.

public static SearchResponse searchResultWithAggregation(String es_index,
        String es_type, List<String> ipList, String queryRangeTime) {
        Client client = ESClientFactory.getInstance();

    QueryBuilder qb = QueryBuilders.boolQuery()
            .must(QueryBuilders.termQuery("address", "10.203.238.138"))
            .must(QueryBuilders.termQuery("address", "10.203.238.137"))
            .must(QueryBuilders.termQuery("address", "10.203.238.136"))
            .mustNot(QueryBuilders.termQuery("address", "10.203.238.140"))
            .should(QueryBuilders.termQuery("client", ""));

    queryRangeTime = "now-" + queryRangeTime + "m";
    FilterBuilder fb = FilterBuilders.rangeFilter("@timestamp")
            .from(queryRangeTime).to("now");

    SearchResponse response = client
            .prepareSearch(es_index)
            .setTypes(es_type)
            .setQuery(qb)
            .setPostFilter(fb)
            .addAggregation(
                    AggregationBuilders.avg("cpu_average").field("value"))
            .setSize(10).execute().actionGet();

    System.out.println(response.toString());
    return response;
}
like image 779
bagui Avatar asked Jun 04 '14 16:06

bagui


2 Answers

You can use the terms query to pass multiple values for single field. create a string array or set. and pass it to the terms query.

  Set<String> address = new HashSet<String>();
  address.add("10.203.238.138");
  address.add("10.203.238.137");
  address.add("10.203.238.136");
  if(address!=null)
     QueryBuilder qb = QueryBuilders.boolQuery()
                .must(QueryBuilders.termsQuery("address",address))
                .mustNot(QueryBuilders.termQuery("address", "10.203.238.140"))
                .should(QueryBuilders.termQuery("client", ""));
  else
     QueryBuilder qb = QueryBuilders.boolQuery()
                .mustNot(QueryBuilders.termQuery("address", "10.203.238.140"))
                .should(QueryBuilders.termQuery("client", ""));

Hope it helps..!

like image 156
BlackPOP Avatar answered Nov 20 '22 06:11

BlackPOP


If you use TermsQuery for address array/set, it will return any documents that match with at least one or more of the provided terms.

List<String> address = new ArrayList<String>();
address.add("10.203.238.138");
address.add("10.203.238.137");
address.add("10.203.238.136");

BoolQueryBuilder qb = QueryBuilders.boolQuery();
qb.mustNot(QueryBuilders.termQuery("address", "10.203.238.140"));
qb.should(QueryBuilders.termQuery("client", ""));

for(String add: Address){
    qb.must(QueryBuilders.termsQuery("address",add));
}
like image 43
Vineet Kumar Singh Avatar answered Nov 20 '22 06:11

Vineet Kumar Singh