0
construction

Je construis les indices comme:Recherche partielle ne fonctionne pas sur ElasticSearch + Haystack malgré l'utilisation Ngram et Edgengram pour l'indice

class BookIndex(indexes.SearchIndex,indexes.Indexable): 

text= indexes.EdgeNgramField(document=True,use_template=True) 
content_auto = indexes.EdgeNgramField(model_attr='title') 
isbn_13 = indexes.CharField(model_attr='isbn_13') 
validate = indexes.IntegerField(model_attr='validate') 
price = indexes.IntegerField(model_attr='price') 
authors = indexes.EdgeNgramField() 
reviews = indexes.CharField() 
publishers = indexes.EdgeNgramField() 
institutes = indexes.EdgeNgramField() 
sellers = indexes.CharField() 
category = indexes.CharField() 
sub_category = indexes.CharField() 

J'ai même essayé d'utiliser Ngram mais recherche partielle ne fonctionne pas.

Je l'interroge comme SearchQuerySet().all().filter(content=query) J'ai également essayé SearchQuerySet().filter(content__contains=query) même alors il ne montre pas les résultats pour la correspondance partielle.

Quelqu'un peut-il m'aider s'il vous plaît?

Répondre

1

Haystack est pas très bon avec ElasticSearch, vous ne pouvez pas utiliser des valeurs d'indexation appropriées de sorte que vous devez fournir ElasticSearchBackEnd personnalisé pour l'activer:

#in a search_backends.py file 
from django.conf import settings 
from haystack.backends.elasticsearch_backend import (
    ElasticsearchSearchBackend, 
    ElasticsearchSearchEngine 
) 
from haystack.fields import EdgeNgramField as BaseEdgeNgramField, NgramField as BaseNgramField 
from haystack.indexes import CharField 

#just an example of which degree of configuration could be possible 
CUSTOM_FIELD_TYPE = { 
    'completion': { 
     'type': 'completion', 
     'payloads': True, 
     'analyzer': 'suggest_analyzer', 
     'preserve_separators': True, 
     'preserve_position_increments': False 
    }, 
} 

# Custom Backend 
class CustomElasticBackend(ElasticsearchSearchBackend): 

    DEFAULT_ANALYZER = None 

    def __init__(self, connection_alias, **connection_options): 
     super(CustomElasticBackend, self).__init__(
           connection_alias, **connection_options) 
     user_settings = getattr(settings, 'ELASTICSEARCH_INDEX_SETTINGS', None) 
     self.DEFAULT_ANALYZER = getattr(settings, 'ELASTICSEARCH_DEFAULT_ANALYZER', "snowball") 
     if user_settings: 
      setattr(self, 'DEFAULT_SETTINGS', user_settings) 

    def build_schema(self, fields): 
     content_field_name, mapping = super(CustomElasticBackend, 
               self).build_schema(fields) 

     for field_name, field_class in fields.items(): 
      field_mapping = mapping[field_class.index_fieldname] 

      index_analyzer = getattr(field_class, 'index_analyzer', None) 
      search_analyzer = getattr(field_class, 'search_analyzer', None) 
      field_analyzer = getattr(field_class, 'analyzer', self.DEFAULT_ANALYZER) 

      if field_mapping['type'] == 'string' and field_class.indexed: 
       field_mapping["term_vector"] = "with_positions_offsets" 
       if not hasattr(field_class, 'facet_for') and not field_class.field_type in('ngram', 'edge_ngram'): 
        field_mapping['analyzer'] = field_analyzer 

      if field_class.field_type in CUSTOM_FIELD_TYPE: 
       field_mapping = CUSTOM_FIELD_TYPE.get(field_class.field_type).copy() 

      if index_analyzer and search_analyzer: 
       field_mapping['index_analyzer'] = index_analyzer 
       field_mapping['search_analyzer'] = search_analyzer 
       if 'analyzer' in field_mapping: 
        del(field_mapping['analyzer']) 

      mapping.update({field_class.index_fieldname: field_mapping}) 
     return (content_field_name, mapping) 


class CustomElasticSearchEngine(ElasticsearchSearchEngine): 
    backend = CustomElasticBackend 


# Custom fields, just use the ones you need or create yours 
class CustomFieldMixin(object): 

    def __init__(self, **kwargs): 
     self.analyzer = kwargs.pop('analyzer', None) 
     self.index_analyzer = kwargs.pop('index_analyzer', None) 
     self.search_analyzer = kwargs.pop('search_analyzer', None) 
     super(CustomFieldMixin, self).__init__(**kwargs) 

class CustomCharField(CustomFieldMixin, CharField): 
    pass 


class CustomCompletionField(CustomFieldMixin, CharField): 
    field_type = 'completion' 


class CustomEdgeNgramField(CustomFieldMixin, BaseEdgeNgramField): 
    pass 


class CustomNgramField(CustomFieldMixin, BaseNgramField): 
    pass 




#settings.py 
ELASTICSEARCH_INDEX_SETTINGS = { 
    'settings': { 
     "analysis": { 
      "analyzer": { 
       "custom_analyzer": { 
        "type": "custom", 
        "tokenizer": "standard", 
        "filter": [ "lowercase", "asciifolding" ] 
       }, 
       "str_index_analyzer" : { 
        "type": "custom", 
        "tokenizer" : "haystack_ngram_tokenizer", 
        "filter" : ["stopwords", "asciifolding", "lowercase", "snowball", "elision", "worddelimiter"] 
       }, 
       "str_search_analyzer" : { 
        "type": "custom", 
        "tokenizer" : "standard", 
        "filter" : ["stopwords", "asciifolding", "lowercase", "snowball", "elision", "worddelimiter"] 
       }, 
       "suggest_analyzer": { 
        "type":"custom", 
        "tokenizer":"standard", 
        "filter":[ 
         "stopwords", 
         "standard", 
         "lowercase", 
         "asciifolding" 
        ] 
       }, 
      }, 
      "tokenizer": { 
       "haystack_ngram_tokenizer": { 
        "type": "nGram", 
        "min_gram": 2, 
        "max_gram": 20, 
       }, 
      }, 
      "filter": { 
       "elision": { 
        "type": "elision", 
        "articles": ["l", "m", "t", "qu", "n", "s", "j", "d"] 
       }, 
       "stopwords": { 
        "type": "stop", 
        "stopwords": ["_french_", "_english_"], 
        "ignore_case": True 
       }, 
       "worddelimiter": { 
        "type": "word_delimiter" 
       } 
      } 
     } 
    } 
} 

#Haystack settings 
HAYSTACK_CONNECTIONS = { 
    'default': { 
     ... 
     'ENGINE': 'path.to.search_backends.CustomElasticSearchEngine', 
     ... 
    }, 
} 
+0

Salut, je reçois l'erreur suivante en essayant le code ci-dessus -> http://dpaste.com/33GFKA7 – Subhajit

+0

Oh, j'ai oublié d'ajouter un les paramètres d'importation! Il suffit d'ajouter «à partir de paramètres d'importation django.conf» en haut de votre fichier – Pcriulan

+0

Il ne fonctionne toujours pas pour une correspondance partielle – Subhajit

0

En utilisant elasticsearch-2.x avec django-haystack versions <2.5 provoque ce problème. Vérifiez si vos versions correspondent à celles-ci.

elasticsearch-2.x Ensuite, boost n'est plus une méta-donnée de support que haystack lui passe. (Veuillez vous référer à la réponse https://stackoverflow.com/a/36847352/5108155)
Ce problème a été corrigé dans 2.5 verison de haystack.

Lors de la création (ou de la mise à jour) de votre index, elasticsearch n'a jamais reçu l'analyseur de ngram que vous vouliez appliquer au champ. Vous pouvez le valider manuellement- curl 'http://<elasticsearch_address>/<index_name>/?pretty' Ceci montrera seulement les types sur les champs et aucune propriété d'analyseur.

Il est intéressant de noter que haystack ne lance pas cette exception à cause d'une propriété interne silently_fail dans la classe ElasticSearchBackend.