title: spring-data-elasticsearch using Criteria with nested Objects
body: <p>I'm quite new to elasticsearch and spring-data-elasticsearch and I have some problems querying for nested objects.</p>
  
  <p>I use the ElasticSearch repository to save an nested model instance in elasticsearch. As a result there is only one entry in elasticsearch containing all data, as far I understood this means I have a nested document.</p>
  
  <p>I need to implement a relatively complex query using Criteria to build up the query iteratively.
  When I try to access a nested property using the dot notation like</p>
  
  <pre><code>startPoint.providingTimeRange.startTime
  </code></pre>
  
  <p>I don't get any search results (but matching data is present in elasticsearch).</p>
  
  <p>In <a href="https://stackoverflow.com/questions/18831882/spring-data-elastic-search-with-nested-fields-and-mapping">Spring Data Elastic Search with Nested Fields and mapping</a> I found the capability of spring-data-elasticsearch to query for nested objects using the nestedQuery.</p>
  
  <p>Is there any way to combine the Criteria search with the nestedQuery?</p>
  
  <p>Thank you in advance,
  Christoph</p>
  
  <p><strong>Update 1:</strong>
  To provide some example code I created a demo project which contains similar nested objects like in my real project: <a href="https://github.com/empulse-gmbh/elasticsearchtest" rel="nofollow noreferrer">https://github.com/empulse-gmbh/elasticsearchtest</a></p>
  
  <p>The example is about to find FoodTrucks which are in a certain place in a certain time. </p>
  
  <p>In this example I used a Repository to persist my nested entities.</p>
  
  <p>I used two (both not working) approaches to query for nested objects:</p>
  
  <pre><code>        /*
           * add search criteria by timerange. it is assumed in timerange from
           * is always before to.
           */
          TimeRange searchTimeRange = foodTruckSearch.getSearchTimeRange();
          if (searchTimeRange != null) {
  
              String startTimePath = "locationPoint.timeRange.from";
              String endTimePath = "locationPoint.timeRange.to";
  
              searchCriteria = searchCriteria.and(
                      new Criteria(startTimePath).between(searchTimeRange
                              .getFrom().getTime(), searchTimeRange.getTo()
                              .getTime())).or(
                      new Criteria(endTimePath).between(searchTimeRange
                              .getFrom().getTime(), searchTimeRange.getTo()
                              .getTime()));
          }
  </code></pre>
  
  <p>and:</p>
  
  <pre><code>    TimeRange searchTimeRange = foodTruckSearch.getSearchTimeRange();
      if (searchTimeRange != null) {
  
          String startTimePath = "locationPoint.timeRange.from";
          String endTimePath = "locationPoint.timeRange.to";
  
          searchQuery.must(nestedQuery(
                  "locationPoint",
                  boolQuery().should(
                          rangeQuery(startTimePath).from(
                                  searchTimeRange.getFrom().getTime()).to(
                                  searchTimeRange.getTo().getTime())).should(
                          rangeQuery(endTimePath).from(
                                  searchTimeRange.getFrom()).to(
                                  searchTimeRange.getTo()))));
  
      }
  </code></pre>
  
  <p><strong>Update2:</strong>
  Thanks to Mohsin Husen I was able to use the nested search. The search by timerange works now.
  Additionally to Mohsin's suggestions I had to change the way of creating and starting the local Elasticsearch instance:</p>
  
  <pre><code>elasticSearchNode = NodeBuilder.nodeBuilder().clusterName("foodtruck-test").local(true).build();
  </code></pre>
  
  <p>Without giving the clusterName nested documents are not created.</p>
  
  <p>My next (hopefully last) problem is using the geo_distance search filter. If I got it right in Elasticsearch I use queries for fuzzy searches like 'like' or 'range' and filters for yes/no or distance filters.</p>
  
  <p>So I tried to use QueryBuilder and FilterBuilder together with spring-data-elasticsearch and failed.</p>
  
  <p>According to the examples in the documentation I refactored my models so the Location class uses the spring-data-elasticsearch object GeoPoint.</p>
  
  <p>For searching I use this:</p>
  
  <pre><code>    /*
       * add search criteria for radius search
       */
      FilterBuilder searchFilter = null;
      if (foodTruckSearch.getLatitude() != null
              &amp;&amp; foodTruckSearch.getLongitude() != null) {
  
          if (foodTruckSearch.getSearchRadiusInKilometers() == null) {
              foodTruckSearch.setSearchRadiusInKilometers(5);
          }
  
          searchFilter = geoDistanceFilter("location.point")
                  .distance(
                          foodTruckSearch.getSearchRadiusInKilometers()
                                  + "km").lat(foodTruckSearch.getLatitude())
                  .lon(foodTruckSearch.getLongitude());
  
      }
  
      if (searchFilter != null) {
          NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(
                  searchQuery, searchFilter);
          return IteratorUtils.toList(foodTruckRepository.search(
                  nativeSearchQuery).iterator());
      } else {
          return IteratorUtils.toList(foodTruckRepository.search(searchQuery)
                  .iterator());
      }
  </code></pre>
  
  <p>The exception I get is:</p>
  
  <pre><code>org.elasticsearch.action.search.SearchPhaseExecutionException: Failedtoexecutephase[query_fetch],
  allshardsfailed;shardFailures{
      [1][searchexample][0]: SearchParseException[[searchexample][0]: query[MatchNoDocsQuery],
      from[0],
      size[10]: ParseFailure[Failedtoparsesource[{
      "from": 0,
      "size": 10,
      "query": {
          "bool": {
  
          }
      },
      "post_filter": {
          "geo_distance": {
              "location.point": [6.9599115,
              50.9406645],
              "distance": "10km"
          }
      }
  }]]];nested: QueryParsingException[[searchexample]failedtofindgeo_pointfield[location.point]]   ;
  }
  </code></pre>
  
  <p>Is there any example available how to use geo_distance (nested?) filters with spring-data-elasticsearch?</p>