Skip to content

Commit

Permalink
prepare 0.4.2
Browse files Browse the repository at this point in the history
  • Loading branch information
barseghyanartur committed Sep 27, 2017
1 parent aa6040c commit 34b2225
Show file tree
Hide file tree
Showing 12 changed files with 328 additions and 24 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ are used for versioning (schema follows below):
0.3.4 to 0.4).
- All backwards incompatible changes are mentioned in this document.

0.4.2
-----
2017-09-28

- Added ``geo_bounding_box`` query support to the geo-spatial features.

0.4.1
-----
2017-09-26
Expand Down
3 changes: 2 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ Main features and highlights
``lte``, ``endswith``, ``contains``, ``wildcard``, ``exists``, ``exclude``,
``isnull``, ``range``, ``in``, ``term`` and ``terms`` is implemented.
- :doc:`Geo-spatial filtering filter backend <advanced_usage_examples>` (the
following filters implemented: ``geo_distance``, ``geo_polygon``).
following filters implemented: ``geo_distance``, ``geo_polygon`` and
``geo_bounding_box``).
- :doc:`Geo-spatial ordering filter backend <advanced_usage_examples>` (the
following filters implemented: ``geo_distance``).
- :doc:`Faceted search filter backend <advanced_usage_examples>`.
Expand Down
8 changes: 8 additions & 0 deletions advanced_usage_examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,14 @@ Filter documents that are located in the given polygon.
http://localhost:8000/search/publishers/?location__geo_polygon=40,-70|30,-80|20,-90
**Geo-bounding-box filtering**

Filter documents that are located in the given bounding box.

.. code-block:: text
http://localhost:8000/search/publishers/?location__geo_bounding_box=44.87,40.07|43.87,41.11
Ordering
~~~~~~~~

Expand Down
8 changes: 8 additions & 0 deletions docs/advanced_usage_examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,14 @@ Filter documents that are located in the given polygon.
http://localhost:8000/search/publishers/?location__geo_polygon=40,-70|30,-80|20,-90
**Geo-bounding-box filtering**

Filter documents that are located in the given bounding box.

.. code-block:: text
http://localhost:8000/search/publishers/?location__geo_bounding_box=44.87,40.07|43.87,41.11
Ordering
~~~~~~~~

Expand Down
6 changes: 6 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ are used for versioning (schema follows below):
0.3.4 to 0.4).
- All backwards incompatible changes are mentioned in this document.

0.4.2
-----
2017-09-28

- Added ``geo_bounding_box`` query support to the geo-spatial features.

0.4.1
-----
2017-09-26
Expand Down
3 changes: 2 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ Main features and highlights
``lte``, ``endswith``, ``contains``, ``wildcard``, ``exists``, ``exclude``,
``isnull``, ``range``, ``in``, ``term`` and ``terms`` is implemented.
- :doc:`Geo-spatial filtering filter backend <advanced_usage_examples>` (the
following filters implemented: ``geo_distance``, ``geo_polygon``).
following filters implemented: ``geo_distance``, ``geo_polygon`` and
``geo_bounding_box``).
- :doc:`Geo-spatial ordering filter backend <advanced_usage_examples>` (the
following filters implemented: ``geo_distance``).
- :doc:`Faceted search filter backend <advanced_usage_examples>`.
Expand Down
3 changes: 3 additions & 0 deletions examples/simple/search_indexes/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
LOOKUP_FILTER_WILDCARD,
LOOKUP_FILTER_GEO_DISTANCE,
LOOKUP_FILTER_GEO_POLYGON,
LOOKUP_FILTER_GEO_BOUNDING_BOX,
LOOKUP_QUERY_IN,
LOOKUP_QUERY_GT,
LOOKUP_QUERY_GTE,
Expand Down Expand Up @@ -290,8 +291,10 @@ class PublisherDocumentViewSet(BaseDocumentViewSet):
geo_spatial_filter_fields = {
'location': {
'lookups': [
LOOKUP_FILTER_GEO_BOUNDING_BOX,
LOOKUP_FILTER_GEO_DISTANCE,
LOOKUP_FILTER_GEO_POLYGON,

],
},
}
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from setuptools import find_packages, setup

version = '0.4.1'
version = '0.4.2'

DOCS_TRANSFORMATIONS = (
(
Expand Down
2 changes: 1 addition & 1 deletion src/django_elasticsearch_dsl_drf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""

__title__ = 'django-elasticsearch-dsl-drf'
__version__ = '0.4.1'
__version__ = '0.4.2'
__author__ = 'Artur Barseghyan <[email protected]>'
__copyright__ = '2017 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
Expand Down
50 changes: 50 additions & 0 deletions src/django_elasticsearch_dsl_drf/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
'EXTENDED_STRING_LOOKUP_FILTERS',
'FALSE_VALUES',
'LOOKUP_FILTER_EXISTS',
'LOOKUP_FILTER_GEO_BOUNDING_BOX',
'LOOKUP_FILTER_GEO_DISTANCE',
'LOOKUP_FILTER_GEO_POLYGON',
'LOOKUP_FILTER_PREFIX',
Expand Down Expand Up @@ -194,9 +195,11 @@

# Draws a circle around the specified location and finds all documents that
# have a geo-point within that circle.
#
# The `geo_distance` filter. Accepts three values (distance|lat|lon)
# separated by `SEPARATOR_LOOKUP_VALUE`.
# https://www.elastic.co/guide/en/elasticsearch/guide/current/geo-distance.html
#
# Example:
#
# {
Expand Down Expand Up @@ -249,14 +252,60 @@
# }
#
# Query options:
#
# - _name: Optional name field to identify the filter
# - validation_method: Set to IGNORE_MALFORMED to accept geo points with
# invalid latitude or longitude, COERCE to try and infer correct latitude or
# longitude, or STRICT (default is STRICT).
#
# Example: http://localhost:8000
# /api/articles/?location__geo_polygon=40,-70|30,-80|20,-90
LOOKUP_FILTER_GEO_POLYGON = 'geo_polygon'

# Geo Bounding Box Query
# A query allowing to filter hits based on a point location using a bounding
# box. Assuming the following indexed document:
#
# Example:
#
# {
# "query": {
# "bool" : {
# "must" : {
# "match_all" : {}
# },
# "filter" : {
# "geo_bounding_box" : {
# "location" : {
# "top_left" : {
# "lat" : 40.73,
# "lon" : -74.1
# },
# "bottom_right" : {
# "lat" : 40.01,
# "lon" : -71.12
# }
# }
# }
# }
# }
# }
# }
#
# Query options:
#
# - _name: Optional name field to identify the filter
# - validation_method: Set to IGNORE_MALFORMED to accept geo points with
# invalid latitude or longitude, COERCE to try and infer correct latitude or
# longitude, or STRICT (default is STRICT).
# - type: Set to one of indexed or memory to defines whether this filter will
# be executed in memory or indexed. See Type below for further details.
# Default is memory.
#
# Example: http://localhost:8000
# /api/articles/?location__geo_bounding_box=40.73,-74.1|40.01,-71.12
LOOKUP_FILTER_GEO_BOUNDING_BOX = 'geo_bounding_box'

# ****************************************************************************
# ************************ Functional filters/queries ************************
# ****************************************************************************
Expand Down Expand Up @@ -372,6 +421,7 @@
)

ALL_GEO_SPATIAL_LOOKUP_FILTERS_AND_QUERIES = (
LOOKUP_FILTER_GEO_BOUNDING_BOX,
LOOKUP_FILTER_GEO_DISTANCE,
LOOKUP_FILTER_GEO_POLYGON,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
are contained by, or do not intersect with the specified geo-shape.
- geo_bounding_box query: Finds documents with geo-points that fall into
the specified rectangle.
- geo_distance query: Finds document with geo-points within the specified
+ geo_distance query: Finds document with geo-points within the specified
distance of a central point.
- geo_distance_range query: Like the geo_distance query, but the range
starts at a specified distance from the central point.
- geo_polygon query: Find documents with geo-points within the specified
starts at a specified distance from the central point. Note, that this
one is deprecated and this isn't implemented.
+ geo_polygon query: Find documents with geo-points within the specified
polygon.
"""

Expand All @@ -30,6 +31,7 @@
ALL_GEO_SPATIAL_LOOKUP_FILTERS_AND_QUERIES,
LOOKUP_FILTER_GEO_DISTANCE,
LOOKUP_FILTER_GEO_POLYGON,
LOOKUP_FILTER_GEO_BOUNDING_BOX,
SEPARATOR_LOOKUP_COMPLEX_VALUE,
SEPARATOR_LOOKUP_COMPLEX_MULTIPLE_VALUE,
)
Expand Down Expand Up @@ -227,6 +229,111 @@ def get_geo_polygon_params(cls, value, field):
return params
return {}

@classmethod
def get_geo_bounding_box_params(cls, value, field):
"""Get params for `geo_bounding_box` query.
Example:
/api/articles/?location__geo_bounding_box=40.73,-74.1|40.01,-71.12
Example:
/api/articles/?location__geo_polygon=40.73,-74.1|40.01,-71.12
|_name:myname|validation_method:IGNORE_MALFORMED|type:indexed
Elasticsearch:
{
"query": {
"bool" : {
"must" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"person.location" : {
"top_left" : {
"lat" : 40.73,
"lon" : -74.1
},
"bottom_right" : {
"lat" : 40.01,
"lon" : -71.12
}
}
}
}
}
}
}
:param value:
:param field:
:type value: str
:type field:
:return: Params to be used in `geo_bounding_box` query.
:rtype: dict
"""
__values = cls.split_lookup_value(value)
__len_values = len(__values)

if not __len_values:
return {}

__top_left_points = {}
__bottom_right_points = {}
__options = {}

# Top left
__lat_lon = __values[0].split(
SEPARATOR_LOOKUP_COMPLEX_MULTIPLE_VALUE
)
if len(__lat_lon) >= 2:
__top_left_points.update({
'lat': float(__lat_lon[0]),
'lon': float(__lat_lon[1]),
})

# Bottom right
__lat_lon = __values[1].split(
SEPARATOR_LOOKUP_COMPLEX_MULTIPLE_VALUE
)
if len(__lat_lon) >= 2:
__bottom_right_points.update({
'lat': float(__lat_lon[0]),
'lon': float(__lat_lon[1]),
})

# Options
for __value in __values[2:]:
if SEPARATOR_LOOKUP_COMPLEX_VALUE in __value:
__opt_name_val = __value.split(
SEPARATOR_LOOKUP_COMPLEX_VALUE
)
if len(__opt_name_val) >= 2:
if __opt_name_val[0] in ('_name',
'validation_method',
'type'):
__options.update(
{
__opt_name_val[0]: __opt_name_val[1]
}
)

if not __top_left_points or not __bottom_right_points:
return {}

params = {
field: {
'top_left': __top_left_points,
'bottom_right': __bottom_right_points,
}
}
params.update(__options)

return params

@classmethod
def apply_query_geo_distance(cls, queryset, options, value):
"""Apply `geo_distance` query.
Expand Down Expand Up @@ -267,6 +374,26 @@ def apply_query_geo_polygon(cls, queryset, options, value):
)
)

@classmethod
def apply_query_geo_bounding_box(cls, queryset, options, value):
"""Apply `geo_bounding_box` query.
:param queryset: Original queryset.
:param options: Filter options.
:param value: value to filter on.
:type queryset: elasticsearch_dsl.search.Search
:type options: dict
:type value: str
:return: Modified queryset.
:rtype: elasticsearch_dsl.search.Search
"""
return queryset.query(
Q(
'geo_bounding_box',
**cls.get_geo_bounding_box_params(value, options['field'])
)
)

def get_filter_query_params(self, request, view):
"""Get query params to be filtered on.
Expand Down Expand Up @@ -350,4 +477,12 @@ def filter_queryset(self, request, queryset, view):
value
)

# `geo_bounding_box` query lookup
elif options['lookup'] == LOOKUP_FILTER_GEO_BOUNDING_BOX:
queryset = self.apply_query_geo_bounding_box(
queryset,
options,
value
)

return queryset
Loading

0 comments on commit 34b2225

Please sign in to comment.