1

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

1 に答える 1