Reputation: 3526
I've been using a distance filter using regular django query filters within an OR-clause:
# either it's within the preset distance of the location
# OR it's not an in-person event
self.filter(Q(location__distance_lt=(geometry, LOCATION_WITHIN_D)) | ~Q(type=Event.IN_PERSON))
I want to do a similar filtering as part of a haystack query, using SQ:
queryset = queryset.filter(SQ(location__distance_lt=(geometry, LOCATION_WITHIN_D)) | ~SQ(type=Event.IN_PERSON))
but instead I get back the error: not all arguments converted during string formatting
- and that only happens with the distance_lt query part, not the ~SQ(type..)
I'm able to apply the distance filtering with my haystack search query by using
queryset = queryset.dwithin('location', geometry, LOCATION_WITHIN_D)`
but I want to be able to have that 'or' condition in this sub-clause.
Is this even possible with raw querying? How can I construct such a raw query for ElasticSearch and still execute it as part of my haystack query?
Upvotes: 2
Views: 296
Reputation: 6296
Got into this exact issue with the same virtual Event scenario (what are the chances right??). Seems the way to go about it is to split the querysets at that point and combine them afterwards
qs1 = queryset.dwithin('location', geometry, LOCATION_WITHIN_D)
qs2 = queryset.exclude(type=Event.IN_PERSON)
queryset = qs1 | qs2
Upvotes: 0
Reputation: 38982
You can perform the search against the Elasticsearch connection.
from django.contrib.gis.measure import D
from haystack.query import SearchQuerySet
sqs = SearchQuerySet('default')
be = sqs.query.backend
LOCATION_WITHIN_D = D(km=0.1)
geometry = {
"lat": 60.1939,
"lon": 11.1003
}
raw_query = {
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"match": {
"type": Event.IN_PERSON
}
},
{
"geo_distance": {
"distance": str(LOCATION_WITHIN_D),
"location": geometry
}
}
]
}
}
]
}
}
}
result = be.conn.search(body=raw_query, index='name-of-your-index')
Upvotes: 1