私は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"