How to search a model using multiple fields and to set a priority for them?

132 views Asked by At

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:

  1. Jack Hunt, Oklahoma, OK
  2. Jack Smith, Huntsville, AL

When I search for "Jack Hunt" I'm getting:

  1. Jack Smith, Huntsville, AL
  2. 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?

0

There are 0 answers