ElasticSearch - Geo Spatial search on location array

Dear All, I am creating an index with two types Restaurant and Branch with Spring Data. Restaurant has many branches as nested type. When I create this mapping, Spring Data / ElasticSearch automatically converts the location field inside the Branch type as latitude , longitude array, hence geo spatial query is not possible. Here it is:

I want to perform a search on branch.location for geo spatial search, but elastic search is not treating location as geopoint, rather a string array, hence it is not possible, please suggest what I need to do or where I am getting wrong.

class Restaurant {
    @Field( type = FieldType.Nested)
    private List<Branch> branches = new ArrayList<Branch>();
}

class Branch {
   private GeoPoint location;
}

Please format your code using </> icon as explained in this guide. It will make your post more readable.

Or use markdown style like:

```
CODE
```

What does the mapping look like?
What does a typical Json document look like?

Thanks for your response David, I have formated the code. I am attaching the full class of Spring Data Mapping classes:

@Document(indexName = "index", type = "restaurant")
public class Restaurant {

	@Id
	private String id;
	private String name;
	private String name_ar;
	private String description;
	private String description_ar;
	
//	private GeoPoint location;
	
	@Field( type = FieldType.Nested)
	private List<BranchLocation> locations = new ArrayList<BranchLocation>();
//	private Map<Integer, GeoPoint> locations = new HashMap<Integer, GeoPoint>();
	
//	@Field( type = FieldType.Nested)
//	private List<Product> products = new ArrayList<Product>();
	
}

Branches class/mapping in Spring Data:

@Document(indexName = "index", type = "branch")
public class BranchLocation {
	@Id
	private String id;
	private String name;	
	private GeoPoint location	
//	@Field(type = FieldType.Nested, ignoreFields = {"restaurant"})
	private Restaurant restaurant;
}

This correctly creates the mapping as below:

{"index4":{"aliases":{},"mappings":{"branch":{"properties":{"location":{"type":"geo_point"}}},"restaurant":{"properties":{"locations":{"type":"nested","properties":{"location":{"type":"geo_point"}}}}}},"settings":{"index":{"refresh_interval":"1s","number_of_shards":"5","creation_date":"1511004142432","store":{"type":"fs"},"number_of_replicas":"1","uuid":"s8Pa8Ok2Tc2SNUJK-jEC1w","version":{"created":"2040099"}}},"warmers":{}}}

But then I use following code to insert values:

BranchLocation location = new BranchLocation("1001", "", 24.7007637D, 46.6463977D, null);
	locationRepository.save(location);
	BranchLocation location2 = new BranchLocation("1002", "", 24.7034429D,46.6801231D, null);
	locationRepository.save(location2);
	BranchLocation location3 = new BranchLocation("1003", "", 24.7035265D,46.6494806D, null);
	locationRepository.save(location3);
	BranchLocation location4 = new BranchLocation("1004", "", 24.7044622D,46.6869027D, null);
	locationRepository.save(location4);
	
	Restaurant rest = new Restaurant("001", "Bangkok Thai Restaurant", "مطعم بانكوك التايلاندي", "Bangkok Thai Restaurant Description", "مطعم بانكوك التايلاندي");
	rest.getLocations().add(location);
	rest.getLocations().add(location2);
	rest.getLocations().add(location3);
	rest.getLocations().add(location4);
	restaurantService.save(rest);

It changes the mapping to following, when I add data, which is correct now, but I am not able to execute the following query, my index contain 1 restaurant and 4 branches which has geo locations inside it, I want to search a restaurant based on the branch location with the following query, please tell me what I have done wrong here:

Geo Spatial Query:

{
  "from" : 0,
  "size" : 20,
  "query" : {
    "match_all" : { }
  },
  "post_filter" : {
    "geo_distance" : {
      "distance" : "25km",
      "locations.location" : { 
        "lat" : 24.7007637, 
        "lon" : 46.6463977 
      }      
    }
  }
}

After adding data in the index (restaurant and braches):
{"index5":{"aliases":{},"mappings":{"branch":{"properties":{"id":{"type":"string"},"location":{"properties":{"lat":{"type":"double"},"lon":{"type":"double"}}},"name":{"type":"string"}}},"restaurant":{"properties":{"description":{"type":"string"},"description_ar":{"type":"string"},"id":{"type":"string"},"locations":{"type":"nested","properties":{"id":{"type":"string"},"location":{"type":"geo_point"},"name":{"type":"string"}}},"name":{"type":"string"},"name_ar":{"type":"string"}}}},"settings":{"index":{"refresh_interval":"1s","number_of_shards":"5","creation_date":"1511005201064","store":{"type":"fs"},"number_of_replicas":"1","uuid":"5x9T44cKT8uJylT9HDZY_A","version":{"created":"2040099"}}},"warmers":{}}}

Please tell me where I am wrong, why the query is returning empty.

I can see this in your mapping.

"type":"nested"

Which means that when you query you need to use nested queries as well as internally nested documents are specific Lucene documents.

can you please transform the following query to suit my case, looking forward to your support.

{
  "from" : 0,
  "size" : 20,
  "query" : {
    "match_all" : { }
  },
  "post_filter" : {
    "geo_distance" : {
      "distance" : "25km",
      "locations.location" : { 
        "lat" : 24.7007637, 
        "lon" : 46.6463977 
      }
    }
  }
}

Have a look at https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.