Search code examples
djangoelasticsearchelasticsearch-dslelasticsearch-pyelasticsearch-dsl-py

ElasticSearch - bulk indexing for a completion suggester in python


I am trying to add a completion suggester to enable search-as-you-type for a search field in my Django app (using Elastic Search 5.2.x and elasticseach-dsl). After trying to figure this out for a long time, I am not able to figure yet how to bulk index the suggester. Here's my code:

class SchoolIndex(DocType):
    name = Text()
    school_type = Keyword()
    name_suggest = Completion()

Bulk indexing as follows:

def bulk_indexing():
    SchoolIndex.init(index="school_index")
    es = Elasticsearch()
    bulk(client=es, actions=(a.indexing() for a in models.School.objects.all().iterator()))

And have defined an indexing method in models.py:

def indexing(self):
       obj = SchoolIndex(
          meta = {'id': self.pk},
          name = self.name,
          school_type = self.school_type,
          name_suggest = {'input': self.name } <--- # what goes in here?
       )
       obj.save(index="school_index")
       return obj.to_dict(include_meta=True)

As per the ES docs, suggestions are indexed like any other field. So I could just put a few terms in the name_suggest = statement above in my code which will match the corresponding field, when searched. But my question is how to do that with a ton of records? I was guessing there would be a standard way for ES to automatically come up with a few terms that could be used as suggestions. For example: using each word in the phrase as a term. I could come up something like that on my own (by breaking each phrase into words) but it seems counter-intuitive to do that on my own since I'd guess there would already be a default way that the user could further tweak if needed. But couldn't find anything like that on SO/blogs/ES docs/elasticsearch-dsl docs after searching for quite sometime. (This post by Adam Wattis was very helpful in getting me started though). Will appreciate any pointers.


Solution

  • I think I figured it out (..phew)

    In the indexing function, I need to use the following to enable to the prefix completion suggester:

    name_suggest = self.name
    

    instead of:

    name_suggest = {'input': something.here }
    

    which seems to be used for more custom cases.

    Thanks to this video that helped!