包含 GeoPoint 的位置列表 - (geo_spatial_filter_fields, geo_distance)
A list of locations that contain a GeoPoint - (geo_spatial_filter_fields, geo_distance)
我正在使用 elasticsearch-dsl-drf,我刚刚将文档中的一个 location
字段转换为具有以下定义的 NestedField
:
location = fields.NestedField(properties={"point": fields.GeoPointField()})
然后在我看来我有(我添加了 path
并更改了 field
值以尝试使其工作):
geo_spatial_filter_fields = {
'location': {
'path': 'location',
'field': 'point',
'lookups': [constants.LOOKUP_FILTER_GEO_DISTANCE]
}
}
geo_spatial_ordering_fields = {'location': None}
我想知道这是如何实现的?我想根据每个文档的位置列表中最近的位置对所有文档进行排序。
编辑
目前正在试验(更改了 elasticsearch dsl drf 以使用它):
{
"query":{
"nested":{
"path":"location",
"query":{
"geo_distance":{
"distance":"16090km",
"location.point":{
"lat":"52.240995",
"lon":"0.751156"
},
"distance_type":"arc"
}
}
}
},
"sort":[
{
"_geo_distance":{
"location.point":{
"lat":"52.240995",
"lon":"0.751156"
},
"unit":"km",
"distance_type":"plane",
"order":"asc"
}
},
{
"date_first_registered":{
"order":"desc"
}
}
]
}
这似乎可以执行,但排序已关闭。
感谢您抽出时间,
谢谢
elasticsearch-dsl-drf的解决方案
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"
在地理距离排序中包括 "nested_path": "location"
:
{
"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"
}
}
]
}
我正在使用 elasticsearch-dsl-drf,我刚刚将文档中的一个 location
字段转换为具有以下定义的 NestedField
:
location = fields.NestedField(properties={"point": fields.GeoPointField()})
然后在我看来我有(我添加了 path
并更改了 field
值以尝试使其工作):
geo_spatial_filter_fields = {
'location': {
'path': 'location',
'field': 'point',
'lookups': [constants.LOOKUP_FILTER_GEO_DISTANCE]
}
}
geo_spatial_ordering_fields = {'location': None}
我想知道这是如何实现的?我想根据每个文档的位置列表中最近的位置对所有文档进行排序。
编辑
目前正在试验(更改了 elasticsearch dsl drf 以使用它):
{
"query":{
"nested":{
"path":"location",
"query":{
"geo_distance":{
"distance":"16090km",
"location.point":{
"lat":"52.240995",
"lon":"0.751156"
},
"distance_type":"arc"
}
}
}
},
"sort":[
{
"_geo_distance":{
"location.point":{
"lat":"52.240995",
"lon":"0.751156"
},
"unit":"km",
"distance_type":"plane",
"order":"asc"
}
},
{
"date_first_registered":{
"order":"desc"
}
}
]
}
这似乎可以执行,但排序已关闭。
感谢您抽出时间, 谢谢
elasticsearch-dsl-drf的解决方案
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"
在地理距离排序中包括 "nested_path": "location"
:
{
"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"
}
}
]
}