Search code examples
pythondjangodjango-haystack

How to use search with Elasticsearch


I using python 2.7.11 and djnago 1.10.2. I created product models and saved 1000 products in my database.(postgrelsql) Actually, I used Django elasticsearch but its not working. its search only base on product name, i required if search category, colour, etc. Then show releated product. I tryed example.

from haystack import indexes
from product.models import Product

class ProductIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    product_name = indexes.CharField(model_attr='product_name')
    product_colour = indexes.CharField(model_attr='product_colour')

    def get_model(self):
        return Product

    def index_queryset(self, using=None):
        return self.get_model().objects.all() 

I created ProductColour models and used product_colour foreignkey in product moedls. If i search product_colour then display all releated data.

Following some steps :-

  • Install django-haystack.
  • Added haystack in INSTALLED_APPS settings.py file.
  • Modify settings.py file.

    HAYSTACK_CONNECTIONS = {
        'default': {
            'ENGINE': 'haystack.backends.simple_backend.SimpleEngine',
        },
    }
    
  • Added url in urls.py.

    urlpatterns = patterns('',
        url(r'^/search/?$', MySearchView.as_view(), name='search_view'),
    )
    
  • product model.

    class Product(models.Model):
        product_name = models.CharField(max_length=100)
        product_description = models.TextField(default=None, blank=True, null=True)
        product_colour = models.ManyToManyField(ProductColour, blank=True, default=None)
        .......
        .......
        .......
    
  • search.html.

    <form method="get" action=".">
        <table>
            {{ form.as_table }}
            <tr>
                <td>&nbsp;</td>
                <td>
                    <input type="submit" value="Search">
                </td>
            </tr>
        </table>
    </form>
    

Solution

  • I used Django elasticsearch but its not working.

    Acording to your haystack settings you are not using Elasticsearch. You are using the SimpleEngine which is no real search engine at all. To use Elasticsearch your settings must contain this instead:

    HAYSTACK_CONNECTIONS = {
        'default': {
            'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
            'URL': 'http://127.0.0.1:9200/',
            'INDEX_NAME': 'haystack',
        },
    }
    

    Note that haystack is not the search engine itself. It is just a tool to use several search engines from inside your django application. Have you already installed elasticsearch?

    At the moment it doesn't work i guess, because the SimpleEngine can not handle your Many2ManyField correctly.

    In your ProductIndex you defined the product_colour as a CharField. But you referenced the whole related model instance from your ProductColour model. Use a MultiValueField to do this:

    from haystack import indexes
    from product.models import Product
    
    class ProductIndex(indexes.SearchIndex, indexes.Indexable):
        text = indexes.CharField(document=True, use_template=True)
        product_name = indexes.CharField(model_attr='product_name')
    
        # use a MultiValueField for your m2m relation
        product_colours = indexes.MultiValueField()
    
        # define this method that returns all the values for your product_colours index field
        # it must be called "prepare_{your field name}"
        def prepare_product_colours(self, object):
            return [colour.name for color in object.product_colour.all()]
    

    Then you will need a template for your search index where the content of the text field will be generated as described in the haystack documentation.