Home > Software design >  Elasticsearch - Sort By Distance Not Working?
Elasticsearch - Sort By Distance Not Working?

Time:02-03

I have an index where the records are stored in the following format:

"_source": {
  "name": "ACME Pallets",
  "about": null,
  "slug": "acme-pallets",
  "serviceAreas": [
      {
          "admin1": "usa",
          "admin2": null,
          "admin3": null,
          "admin4": null,
          "countryCode": "US",
          "googlePlaceId": null,
          "locality": null,
          "selectedLevel": "admin1"
      }
  ],
  "id": "fadsflsjdfkk3234234",
  "addresses": [
      {
          "address1": "4342 Dietrich Rd",
          "address2": null,
          "city": "San Antonio",
          "countryCode": "US",
          "latitude": 29.44122,
          "longitude": -98.34404,
          "primary": true,
          "name": "office",
          "postal": "78219",
          "province": "TX",
          "location": {
              "lat": 29.44156,
              "lon": -98.37704
          }
      }
  ]
}

I am trying to return results from this index where the records are sorted by distance to the search point I pass in. My sort config being passed in looks like this:

_geo_distance: {
  'addresses.location': { lat: 31.75917, lon: -106.48749 },
  order: 'asc',
  unit: 'mi',
  mode: 'min'
}

The results I receive back are not sorted according to distance. If I manually plot out the individual locations on a map and the search pin passed in, I can see that the sorting is out of order.

If I pass in a sorting config to my search to sort by alphabetically order or to sort by relevance (aka _score), the sorting returned is correct.

Does anyone know why ES might be returning my results incorrectly when sorting by distance?

CodePudding user response:

addresses is an array in my index. Each object inside of addresses has a property called location of type geo_point.

From all the documentation that I've read, passing 'addresses.location': { lat: 31.75917, lon: -106.48749 } into the search should work, but it doesn't. ES should be smart enough to find the location geo point in each object and use that as the reference when calculating the distance. If there are more than one object inside of the addresses array, then ES by default should get the center point of all the objects inside of addresses and use that to calculate the distance from the search point.

In my case, I don't have any data where addresses has more than one object. I ended up creating a location geo_point property outside of the addresses property during index build and then passing in location: { lat: 31.75917, lon: -106.48749 } for the search. This made ES sort results based on distance correctly.

What my new index looks like with the added location property:

"_source": {
  "name": "ACME Pallets",
  "about": null,
  "slug": "acme-pallets",
  "serviceAreas": [
      {
          "admin1": "usa",
          "admin2": null,
          "admin3": null,
          "admin4": null,
          "countryCode": "US",
          "googlePlaceId": null,
          "locality": null,
          "selectedLevel": "admin1"
      }
  ],
  "id": "fadsflsjdfkk3234234",
  "addresses": [
      {
          "address1": "4342 Dietrich Rd",
          "address2": null,
          "city": "San Antonio",
          "countryCode": "US",
          "latitude": 29.44122,
          "longitude": -98.34404,
          "primary": true,
          "name": "office",
          "postal": "78219",
          "province": "TX",
          "location": {
              "lat": 29.44156,
              "lon": -98.37704
          }
      }
  ]
  "location": {
      "lat": 29.44156,
      "lon": -98.37704
  }
}
  • Related