Список местоположений, содержащих GeoPoint - (geo_spatial_filter_fields, geo_distance) - PullRequest
1 голос
/ 17 июня 2020

Я использую 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}

Мне интересно, как этого можно достичь? Я хочу упорядочить все документы на основе ближайшего местоположения из списка местоположений для каждого документа.

Edit

В настоящее время экспериментирую с (изменен elasticsearch dsl drf для использования this):

{
   "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"

1 Ответ

1 голос
/ 17 июня 2020

Включить "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"
         }
      }
   ]
}
...