src/ldt/ldt/indexation/backends/elasticsearch_backend.py
author ymh <ymh.work@gmail.com>
Mon, 20 May 2013 18:02:37 +0200
changeset 1191 b6e0b1811723
parent 1190 129d45eec68c
child 1320 88ce48689c14
permissions -rw-r--r--
Migrate to django 1.5 : - migrate the user profile - do sme cleaning

# -*- coding: utf-8 -*-
'''
Created on Jul 30, 2012

@author: ymh
'''
from haystack.backends import BaseEngine, elasticsearch_backend
from haystack.exceptions import MissingDependency
from haystack.utils import get_identifier
#from ldt.ldt_utils.models import Segment
import collections
try:
    import requests
except ImportError:
    raise MissingDependency("The 'elasticsearch' backend requires the installation of 'requests'.")
try:
    import pyelasticsearch
except ImportError:
    raise MissingDependency("The 'elasticsearch' backend requires the installation of 'pyelasticsearch'. Please refer to the documentation.")



class ElasticsearchSearchBackend(elasticsearch_backend.ElasticsearchSearchBackend):

    def build_search_kwargs(self, query_string, sort_by=None, start_offset=0, end_offset=None,
                        fields='', highlight=False, facets=None,
                        date_facets=None, query_facets=None,
                        narrow_queries=None, spelling_query=None,
                        within=None, dwithin=None, distance_point=None,
                        models=None, limit_to_registered_models=None,
                        result_class=None):
        
        kwargs = super(ElasticsearchSearchBackend, self).build_search_kwargs(query_string, sort_by=sort_by, start_offset=start_offset, end_offset=end_offset,
                        fields=fields, highlight=highlight, facets=facets,
                        date_facets=date_facets, query_facets=query_facets,
                        narrow_queries=narrow_queries, spelling_query=spelling_query,
                        within=within, dwithin=dwithin, distance_point=distance_point,
                        models=models, limit_to_registered_models=limit_to_registered_models,
                        result_class=result_class)
                
        #TODO : try to make list of field dynamic
        #TODO : How to handle multiple 
        if highlight:
            fields_def = { }
 
            if models is None or len(models) == 0 :#or Segment in models:
                fields_def['tags'] = {}
                fields_def['title'] = {}
                fields_def['abstract'] = {}
            
            kwargs['highlight'] = {
                'pre_tags' : ["<span class='highlight'>"],
                'post_tags' : ["</span>"],
                "number_of_fragments" : 0,
                'fields': fields_def                
            }
        
        return kwargs
    
                
    def remove(self, obj_or_string, commit=True):
        
        if not self.setup_complete:
            try:
                self.setup()
            except (requests.RequestException, pyelasticsearch.ElasticHttpError), e:
                if not self.silently_fail:
                    raise

                self.log.error("Failed to remove document '%s' from Elasticsearch: %s", repr(obj_or_string), e)
                return

        if isinstance(obj_or_string, collections.Iterable) and not isinstance(obj_or_string, basestring):
            ids = [get_identifier(elt) for elt in obj_or_string]
            if not ids:
                return
            q = {'ids' : {'values' : ids}}
            self.conn.delete_by_query(self.index_name, 'modelresult', q)
        else: 
            return super(ElasticsearchSearchBackend, self).remove(obj_or_string, commit=commit) 


class ElasticsearchSearchEngine(BaseEngine):
    backend = ElasticsearchSearchBackend
    query = elasticsearch_backend.ElasticsearchSearchQuery