Reputation: 127
I have ES documents similar to this, I have a location array with a type field.
{
"type": "A/B/C",
"locations1": [
{
"lat": 19.0179332,
"lon": 72.868069
},
{
"lat": 18.4421771,
"lon": 73.8585108
}
]
}
Type value determines the distance applicable for that location.
Let's say, the allowed distance of query for type A is 10km, for type B is 100km, for type C is 1000km. Given location L, I want to find all documents which satisfy the distance criteria for that document for the given location and the final result should be sorted by distance.
I am not able to figure out how to use dynamic radius for this. Is it possible or I need to change my document structure similar to this?
EDIT:
I was also thinking of destructing the document locations like this
"locationsTypeA": [
{
"lat": 19.0179332,
"lon": 72.868069
},
{
"lat": 18.4421771,
"lon": 73.8585108
}
],
"locationsTypeB": [
{
"lat": 19.0179332,
"lon": 72.868069
},
{
"lat": 18.4421771,
"lon": 73.8585108
}
],
"locationsTypeC": [
{
"lat": 19.0179332,
"lon": 72.868069
},
{
"lat": 18.4421771,
"lon": 73.8585108
}
]
}
And then I can use the query
"query": {
"bool": {
"should": [
{
"geo_distance": {
"distance": "10km",
"locationsTypeA": {
"lat": 12.5,
"lon": 18.2
}
}
},
{
"geo_distance": {
"distance": "100km",
"locationsTypeB": {
"lat": 12.5,
"lon": 18.2
}
}
},
{
"geo_distance": {
"distance": "1000km",
"locationsTypeC": {
"lat": 12.5,
"lon": 18.2
}
}
}
]
}
}
}
Upvotes: 2
Views: 633
Reputation: 1626
I did the similar but less complex approach
Here's the code:
{
query: {
bool: {
must: [
{
match: {
companyName: {
query: req.text
}
}
},
{
script: {
script: {
params: {
lat: parseFloat(req.lat),
lon: parseFloat(req.lon)
},
source: "doc['location'].arcDistance(params.lat, params.lon) / 1000 < doc['searchRadius'].value",
lang: "painless"
}
}
}
]
}
},
sort: [
{
_geo_distance: {
location: {
lat: parseFloat(req.lat),
lon: parseFloat(req.lon)
},
order: "asc",
unit:"km"
}
}
],
Upvotes: 0
Reputation: 16933
Using the 1st doc structure and the mapping looking like:
PUT geoindex
{
"mappings": {
"properties": {
"locations": {
"type": "geo_point"
}
}
}
}
Let's take a random point between Pune and Mumbai to be the origin relative to which we'll perform a scripted geo query using the arcDistance
function:
GET geoindex/_search
{
"query": {
"bool": {
"must": [
{
"script": {
"script": {
"source": """
def type = doc['type.keyword'].value;
def dynamic_distance;
if (type == "A") {
dynamic_distance = 10e3;
} else if (type == "B") {
dynamic_distance = 100e3;
} else if (type == "C") {
dynamic_distance = 1000e3;
}
def distance_in_m = doc['locations'].arcDistance(
params.origin.lat,
params.origin.lon
);
return distance_in_m < dynamic_distance
""",
"params": {
"origin": {
"lat": 18.81531,
"lon": 73.49029
}
}
}
}
}
]
}
},
"sort": [
{
"_geo_distance": {
"locations": {
"lat": 18.81531,
"lon": 73.49029
},
"order": "asc"
}
}
]
}
Upvotes: 1