I'm using Haystack for searching users in database. I want to check the name of the user, city and state (+abbr of state).
I've done autocomplete using ElasticSearchEdgeNgramField.
# search_indexes.py
class SwimmerIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
name = indexes.CharField(model_attr='get_display_name')
name_auto = ElasticSearchEdgeNgramField(use_template=True, template_name='search/indexes/sdif/swimmer_text.txt', index_analyzer="edgengram_analyzer", search_analyzer="standard_analyzer")
# swimmer_text.txt
{{ object.get_full_nickname }}
{{ object.state }} {{ object.get_state_display }}
{{ object.city }}
And the search.
sqs = sqs.autocomplete(name_auto=request.GET.get('q', ''))
I have 2 users in database:
- Jack Hunt, Oklahoma, OK
- Jack Smith, Huntsville, AL
When I search for "Jack Hunt" I'm getting:
- Jack Smith, Huntsville, AL
- Jack Hunt, Oklahoma, OK
The reason is the city. So I'm searching for the way to boost user if name matches.
I've found one solution.
nickname = indexes.CharField(model_attr='get_full_nickname', boost=1.125)
state = indexes.CharField(model_attr='state', boost=1.0)
state_display_name = indexes.CharField(model_attr='get_state_display', boost=1.0)
city = indexes.CharField(model_attr='city', boost=1.0)
Following the example from https://django-haystack.readthedocs.io/en/master/boost.html
sqs = sqs.filter(SQ(name=AutoQuery(q)) | SQ(state=AutoQuery(q)) | SQ(state_display_name=AutoQuery(q)) | SQ(city=AutoQuery(q)))
But after searching for "Jack Hunt" I haven't got Jack Smith from Huntsville. Since his name is not like "Jack Hunt" and his city is not like "Jack Hunt". I know I can search for each word. But it's not very "elastic".
What can I do to make autocomplete on 4 fields and to give more weight for one of them?