Search code examples
djangoelasticsearchindexingfull-text-searchdjango-haystack

How to exclude unrelated search results from django-haystack and Elasticsearch?


I'm trying to search for products based on their keywords. My haystack index is as follows:

class ProductIndex(indexes.SearchIndex, indexes.Indexable):
    name= indexes.CharField(model_attr='name')
    text = indexes.CharField(document=True) # contains keywords associated with the product

In this case, the field "text" contains a group of keywords associated with the product. For instance, here is a sample product index:

name: "Tide Detergent"
text: "laundry household shopping cleaning supplies"

When I search for laundry, Tide Detergent appears on the search, but so do other irrelevant results, such as products that have lawn or laugh in the text. So it looks like elasticsearch is searching not just for laundry but variations of the word also.

Here is what my search query looks like:

qs = SearchQuerySet().models(Product).filter(content__exact='laundry')

My question is: how can I force haystack or elasticsearch to search strictly for my input keyword and ignore variations of them? In other words, how can ensure that haystack searches for only laundry and exclude any other terms?


Solution

  • I found an answer. I used a raw elasticsearch query instead of going directly through haystack. In that query, I used a constant_score query which will search for exact terms, not fuzzy terms in addition.

    {
        "query":{
            "query":{
                "constant_score":{
                    "filter":{
                        "bool":{
                            "must":[
                                {"bool":{
                                        "must":[
                                            {
                                                "term": {
                                                    "text":"laundry"
                                                }
                                            }
                                        ]
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        }
    }
    

    Here's more info about the constant_score query: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-constant-score-query.html