1

Hello I'm new to Elastic Search and I'm trying to build an elastic search query using Java API. I have the following.

int count = 7
QueryBuilder findRangeNumber = QueryBuilders.rangeQuery("numberField").lte(count);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(findRangeNumber); 

This return numberField that are equal to 12,6,4, and, 5. I want it to return values where numberField is less than or equal to count (so the number 6,5, and 4 in the example).

If I change number count to 12 it only return numberField that are equal to 12. I'm confuse to how this works and if it possible to it return any value of numberField that is less than or equal to count.

I also have tried the following with no luck

int count = 7
QueryBuilder findRangeNumber = QueryBuilders.rangeQuery("numberField").lte(count).gte(0);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(findRangeNumber); 

This is what the query look like when I print out boolQueryBuilder

"must" : [
            {
              "range" : {
                "numberField" : {
                  "from" : null,
                  "to" : 7,
                  "include_lower" : true,
                  "include_upper" : true,
                  "boost" : 1.0
                }
              }
            }
          ],

This is what the full code part look like, of what I'm trying to do.

BoolQueryBuilder boolQuery = new BoolQueryBuilder();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
int count = 7
    if (foo != null) {
        boolQuery.should(QueryBuilders.matchQuery("something", matchSomething));
        boolQuery.should(QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery("foobar status")));
    }

    if (foobar != null) {

        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        queryBuilder.should(QueryBuilders.rangeQuery("someDateField").from(dateField));
        queryBuilder.should(QueryBuilders.rangeQuery("numberField").lte(count));
        boolQuery.must(queryBuilder);

     }

    searchSourceBuilder.query(boolQuery);

Any help would be appreciated!

Toast
  • 25
  • 8

1 Answers1

1

You need to use RangeQueryBuilder to find values that are less than or equal to a given number

Try out this below code

int count=7;
RestHighLevelClient client = new RestHighLevelClient(restClientBuilder);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder("numberField").lte(count);
searchSourceBuilder.query(rangeQueryBuilder);
SearchRequest searchRequest = new SearchRequest("my-index");
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

Update 1:

When you are searching for documents having numberField less than equal to 7, you are getting documents having numberField value 12,6,4,5.

The search result coming is correct. This is possible only if you have not defined an explicit index mapping, due to which when you have indexed the documents having numberField, then it would have been indexed as of text type (by default) instead of numeric field type.

Now, lexically "12","6","4","5" all are smaller than "7", therefore you are getting all the documents in your search result. And when querying for "lte":12, you only get a document having numberField equal to 12. This is because there is no document (among these 4) that is lexically smaller than 12.

You can get the index mapping of your index by using Get Mapping API.

For the range query to work correctly you need to explicitly define the index mapping for your index, where numberField should be mapped to a numeric field datatype. You need to delete your index and create a new index with a new index mapping.

{
  "mappings": {
    "properties": {
      "numberField": {
        "type": "integer"
      }
    }
  }
}
ESCoder
  • 15,431
  • 2
  • 19
  • 42
  • @Toast please go through the answer, and let me know if this resolves your issue ? – ESCoder Apr 11 '21 at 11:39
  • I tried adding the RangeQueryBuilder to the sourcebuilder but I'm already adding a boolean query to it. Is there a way I keep RangeQuery as a boolean Query? – Toast Apr 11 '21 at 13:39
  • @Toast why do you want to add a `BoolQueryBuilder` ? Do you want the range query to be executed inside a `must` clause ? – ESCoder Apr 11 '21 at 13:43
  • looking through a few comments stacking the range query builder on as .should look like in this post here(https://stackoverflow.com/questions/49673744/elasticsearch-java-jest-client-query-builder-range-with-bool-query), but this just made it seem like it wasn't reading any of queries. – Toast Apr 11 '21 at 13:45
  • @Toast which version of Elasticsearch are you using ? Are you using JEST client ? – ESCoder Apr 11 '21 at 13:46
  • @Toast can you please share the query, which you want to convert in Java Code ? – ESCoder Apr 11 '21 at 13:48
  • It doesn't have to act like a must clause but I'm already adding a boolean query to check other fields and I don't think I can add two query to the sourcebuilder – Toast Apr 11 '21 at 13:57
  • I'm using elasticSearch version 6.4.3. I am not using a Jest Client and I don't have the direct query I want, I'm trying to do this directly through the Java code – Toast Apr 11 '21 at 14:25
  • I updated the Question to have more of the original code of what I'm trying to do. Let me know if that helps – Toast Apr 11 '21 at 14:37
  • @Toast please go through the updated part of my answer – ESCoder Apr 11 '21 at 15:56
  • your update make sense. I'm having trouble figuring out how that would look with the Java API – Toast Apr 11 '21 at 17:11
  • @Toast have you defined any index mapping (explicitly) of your index? – ESCoder Apr 11 '21 at 17:18
  • I don't think I do – Toast Apr 11 '21 at 18:25
  • @Toast then you need to define explicit mapping (as shown in the answer above), then your range query will work – ESCoder Apr 11 '21 at 19:07
  • how do I do the above with the Java API? – Toast Apr 12 '21 at 00:56
  • @Toast This would be a completely different answer, it would be better if you ask a separate question related to creating index mapping using Java code. You can refer to this documentation https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-create-index.html – ESCoder Apr 12 '21 at 03:21
  • 1
    of course! Thank you so much for your help! – Toast Apr 12 '21 at 04:10