I am trying to implement search suggestions using django-elasticsearch-dsl-drf
for streets.
This is documents.py
:
class StreetDocument(Document):
id = fields.IntegerField()
name_ru = StringField(
fields={
'raw': KeywordField(),
'suggest': fields.CompletionField(),
}
)
... # same for name_uz and name_oz
tags_ru = fields.CompletionField()
... # same for tags_uz and tags_oz
class Django:
model = Street
fields = (
'code',
'street_type'
)
in views.py
I have this:
from django_elasticsearch_dsl_drf.constants import SUGGESTER_COMPLETION
from django_elasticsearch_dsl_drf.filter_backends import SuggesterFilterBackend, CompoundSearchFilterBackend
from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet
class SuggestionListAPI(DocumentViewSet):
document = StreetDocument
serializer_class = StreetDocumentSerializer
filter_backends = [
CompoundSearchFilterBackend,
SuggesterFilterBackend,
]
search_fields = (
'code',
'name_ru',
'name_uz',
'name_oz',
'tags_ru',
'tags_uz',
'tags_oz'
)
suggester_fields = {
'name_ru_suggest': {
'field': 'name_ru.suggest',
'suggesters': [
SUGGESTER_COMPLETION,
],
},
... # same for name_uz and name_oz
'tags_ru': {
'field': 'tags_ru',
'suggesters': [
SUGGESTER_COMPLETION,
],
},
... # same for tags_uz and tags_oz
}
Request to /suggestions?name_ru_suggest__completion=tolstoy
does nothing, just receiving all streets unfiltered.
Request to /suggestions?search=tolstoy
works great, but I need autocompletion.
Where did I go wrong? And that will be great if it's possible to use two fields for suggestion at once.
Thanks for your time and help.
It looks like you're using wrong endpoint for suggestions. Correct name is suggest
.
Example: http://127.0.0.1:8000/search/publishers/suggest/?country_suggest__completion=Ar
As of your question about using two fields for suggestion at once, it's possible to get suggestions for multiple fields at once. For instance, if you have title
and author
, both properly indexed and configured, you could query it as follows:
http://127.0.0.1:8000/search/books/suggest/?title_suggest=wa&author_suggest=le
This will, however, return you the following result:
{
"title_suggest": [...],
"author_suggest": [...]
}
However, if you need to refine your suggestions based on some criteria, you could do that using context suggesters (search for it in the official documentation of django-elasticsearch-dsl-drf).