Open belthaZornv opened 4 years ago
Solved it by using:
{
"query":{
"nested":{
"path":"location",
"query":{
"geo_distance":{
"distance":"16090km",
"location.point":{
"lat":52.240995,
"lon":0.751156
},
"distance_type":"arc"
}
}
}
},
"sort":[
{
"_geo_distance":{
"nested_path": "location",
"location.point":{
"lat":52.240995,
"lon":0.751156
},
"unit":"km",
"distance_type":"plane",
"order":"asc"
}
},
{
"date_first_registered":{
"order":"desc"
}
}
]
}
Not sure if there is a cleaner way of doing it, but I ended up doing:
def attach_nested_path_to_queryset(queryset: Search):
"""
Attach nested path to the query and sort keys in the queryset
and update the queryset using `update_from_dict`
**The updating is done by reference**
:param queryset: the original queryset
:type queryset: Search
:return:
"""
queryset_dict = queryset.to_dict()
attach_nested_path_to_query(queryset_dict)
attach_nested_path_to_sort(queryset_dict)
# update queryset
queryset.update_from_dict(queryset_dict)
def attach_nested_path_to_query(queryset_dict: dict):
"""
Looks for geo_distance in the queryset dict, if it's at the top level
we modify the top level query, meaning that there's only one query, otherwise
we loop over the list of `must` queries and try to find `geo_distance`
**The updating is done by reference**
:param queryset_dict: the queryset in dict format
:type queryset_dict: dict
:return:
"""
query = queryset_dict["query"]
if "geo_distance" in query:
queryset_dict["query"] = {"nested": {"path": "location", "query": query}}
elif "bool" in query and "must" in query["bool"]:
for index, must_query in enumerate(query["bool"]["must"]):
if "geo_distance" in must_query:
queryset_dict["query"]["bool"]["must"][index] = {"nested": {"path": "location", "query": must_query}}
break
def attach_nested_path_to_sort(queryset_dict: dict):
"""
This function loops over the `sort` queries, and
looks for `_geo_distance` in order to add the `nested_path` key/value
**The updating is done by reference**
:param queryset_dict: the queryset in dict format
:type queryset_dict: dict
:return:
"""
sort = queryset_dict["sort"]
if isinstance(sort, list):
for index, sorting in enumerate(sort):
if "_geo_distance" in sorting:
queryset_dict["sort"][index]["_geo_distance"]["nested_path"] = "location"
Sorry, I'm overwhelmed with work now. I'll check it later (in the weekend).
Thank you @barseghyanartur, I appreciate your reply. :)
If you have some time to give it a look, let me know @barseghyanartur! I understand you're busy though! so thanks for your time dude.
I just converted a single
location
field on my document, to aNestedField
with this definition:location = fields.NestedField(properties={"point": fields.GeoPointField()})
Then on my view I have (I added
path
and changed thefield
value to try and make it work):I'm wondering how this can be achieved? I want to order all the documents based on the closest location from a list of locations for each document.
Edit
Currently experimenting with:
The filtration seems to be working, the sorting, not!
I appreciate your time, Thanks