2

It doesn't seem possible based on https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html , but I'd like confirmation.

In plain English, I'm asking to score the results (with geo-point locations) by how close they are to 500km from some latitude, longitude origin.

It's confusing because there is a parameter called "offset" but according to the documentation it doesn't seem to be an offset from origin (eg. distance) but instead seems to mean "threshold" instead.

Gabe Kopley
  • 16,281
  • 5
  • 47
  • 60
  • 1
    If I get you right, you basically want the decay function to work as if the origin was on a ring at 500km distance from the origin point? Sort of like a wave/donut like this: http://i1-win.softpedia-static.com/screenshots/Gauss_5.jpg – Val Feb 03 '16 at 04:06
  • Yes, I think so, Val! Is that possible with the built-in decay parameters or should I just resort to a custom script? – Gabe Kopley Feb 03 '16 at 23:54
  • Great answer to understand decay function parameters https://stackoverflow.com/a/47844222/1282910 – Patrick Bassut Mar 12 '22 at 14:14

1 Answers1

2

I see a few ways to accomplish this:

A. One way would be to simply sort by distance in reverse order from the origin. You'd use a geo_distance query and then sort by distance. In the following query, the most distant documents will come up first, i.e. the sort value is the distance from the origin and we're sorting in decreasing order.

{
  "query": {
    "filtered": {
      "filter": {
        "geo_distance": {
          "from" : "100km",
          "to" : "200km",
          "location": {
            "lat": 10,
            "lon": 20
          }
        }
      }
    }
  },
  "sort": [
    {
      "_geo_distance": {
        "location": {
          "lat": 10,
          "lon": 20
        },
        "order": "desc",
        "unit": "km",
        "distance_type": "plane"
      }
    }
  ]
}

B. The second way involves using a geo_distance_range query in order to define a "ring" around the origin. The width of that ring could somehow symbolize the offset + scale you'd use in a gauss function (although there would be no decay). Here we define a ring that is 10km wide at 500km distance from the origin point and sort the documents by distance in that ring.

{
  "query": {
    "filtered": {
      "filter": {
        "geo_distance_range": {
          "from": "495km",
          "to": "505km",
          "location": {
            "lat": 10,
            "lon": 20
          }
        }
      }
    }
  },
  "sort": [
    {
      "_geo_distance": {
        "location": {
          "lat": 10,
          "lon": 20
        },
        "order": "desc",
        "unit": "km",
        "distance_type": "plane"
      }
    }
  ]
}

C. The last way is a bit more involved. We're basically after an "inverse gauss" shape, basically this figure (33), but upside-down, or this one which better represents the donut shape we're after. We can combine solution B above with a gauss function that would only score within that ring. In the query below, we're basically saying that we're only interested in the locations around 500km from the origin and we let a gauss function kick in only for those documents. It's not perfect, though, but might be close enough to what you need.

{
  "query": {
    "filtered": {
      "filter": {
        "geo_distance_range": {
          "from": "495km",
          "to": "505km",
          "location": {
            "lat": 10,
            "lon": 20
          }
        }
      },
      "query": {
        "function_score": {
          "functions": [
            {
              "gauss": {
                "location": {
                  "origin": {
                    "lat": 10,
                    "lon": 20
                  },
                  "offset": "500km",
                  "scale": "5km"
                }
              }
            }
          ]
        }
      }
    }
  },
  "sort": {
    "_score": "desc"
  }
}  
Val
  • 207,596
  • 13
  • 358
  • 360
  • Thanks Val! To clarify C), will the gauss function kick in on the range 495 - 505? – Gabe Kopley Feb 04 '16 at 17:07
  • 1
    Yes, only in that range since you won't get any documents before 495km and after 505km. You might need to tune the offset/scale settings, though. – Val Feb 04 '16 at 17:18