Elasticsearch: Geo_spacial search in a list of nested objects

I'm using Elasticsearch 6.3 and spring-data-elasticsearch, I have the index restaurant having the mapping below :

{
 "mapping": {
   "restaurant": {
     "properties": {
       "id": {
         "type": "keyword"
       },
       "name": {
         "type": "text",
         "store": true,
         "analyzer": "custom_analyzer",
         "search_analyzer": "custom_search_analyzer"
       },
       "locations": {
         "type": "nested",
         "include_in_parent": true,
         "properties": {
           "id": {
             "type": "long"
           },
           "fullAddress": {
             "type": "text"
           },
           "geo": {
             "type": "geo_point"
           },
           "phone": {
             "type": "keyword"
           }
         }
       },
       "menus": {
         "type": "nested",
         "properties": {
           "id": {
             "type": "long"
           },
           "name": {
             "type": "text",
             "store": true,
             "analyzer": "custom_analyzer",
             "search_analyzer": "custom_search_analyzer"
           }
         }
       }
     }
   }
 }
}

This is an example of a document of this mapping :

{
 "took": 1,
 "timed_out": false,
 "_shards": {
   "total": 5,
   "successful": 5,
   "skipped": 0,
   "failed": 0
 },
 "hits": {
   "total": 1,
   "max_score": 1,
   "hits": [
     {
       "_index": "restaurants",
       "_type": "restaurants",
       "_id": "1",
       "_score": 1,
       "_source": {
         "id": 1,
         "name": "Mc Donald",
         "menus": [
           {
             "id": 7097,
             "name": "Big Fish"
           },
           {
             "id": 13899,
             "name": "Big Mac"
           }
         ],
         "locations": [
           {
             "id": 1,
             "fullAddress": "7 Bd Solférino, 59000 Lille",
             "geo": { "lat": 50.6423461,"lon": 3.1390441},
             "phone": "0305060804"
           },
           {
             "id": 2,
             "fullAddress": "7 Rue Nationale, 75000 Paris",
             "geo": { "lat": 40.6423461,"lon": -7.1390441},
             "phone": "0305060804"
           }
         ]
       }
     }
   ]
 }
}

I try to search all the restaurants around me, for example, I search the nearest Mc Donald.

I tryed the 2 queries below but they return emty list :

  • Query 1: (Using post filtering)
GET restaurants/_search
{
  "query": {
    "match": {
      "name": "donald"
    }
  },
  "post_filter": {
    "nested": {
      "path": "locations",
      "query": {
        "geo_distance": {
          "distance": "10km",
          "locations.geo": [50.6423461, 3.1390441]
        }
      }
    }
  }
}
  • Query 2: (Using filtering inside query)
GET restaurants/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "donald"
          }
        }
      ],
      "filter": {
        "nested": {
          "path": "locations",
          "query": {
            "geo_distance": {
              "distance": "10km",
              "locations.geo": [50.6423461,3.1390441]
            }
          },
          "inner_hits": {}
        }
      }
    }
  }
}

PLEASE, could someone tell me what I do wrong in my mapping or queries.
Thx in advance

The order of the geo points in the query is incorrect. Note that in that cases (array format) the position must be [lon, lat], as defined here:

https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-point.html

Therefore this query should give you the expected answer:

GET restaurants/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "donald"
          }
        }
      ],
      "filter": {
        "nested": {
          "path": "locations",
          "query": {
            "geo_distance": {
              "distance": "10km",
              "locations.geo": [3.1390441, 50.6423461]
            }
          },
          "inner_hits": {}
        }
      }
    }
  }
}

OK it's so simple, but I had to see it :sweat_smile:
It works like a charm :wink:

Thank you very much.

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