2013-12-18 12 views
5

Ich habe ein Django-Projekt, das SOLR für die Indizierung verwendet.Django Haystack - Nach Teilzeichenfolge eines Feldes mit SearchQuerySet() filtern

Ich versuche, eine String-Suche mit Haystack der SearchQuerySet Klasse zu tun.

Zum Beispiel, wenn ein Nutzer nach dem Begriff „Ohr“, sollte es den Eintrag zurück, die ein Feld mit dem Wert hat: „Suchen“. Wie Sie sehen können, "Ohr" ist ein Teil "Suchen". (Natürlich :))

Mit anderen Worten, in einer perfekten Welt würde Django ich etwas mag wie:

SearchQuerySet().all().filter(some_field__contains_substring='ear') 

im Heuhaufen Dokumentation für SearchQuerySet (https://django-haystack.readthedocs.org/en/latest/searchqueryset_api.html#field-lookups), es sagt, dass nur die folgenden FIELD NACHSCHLAG Typen werden unterstützt:

  • enthält
  • genaue
  • gt, gte, lt, lte
  • in
  • starts
  • Bereich

I __ enthält versucht mit, aber es verhält sich genau wie __exact, die oben sieht das genaues Wort (das ganze Wort) in einem Satz, kein Teilstring eines Wortes.

Ich bin verwirrt, weil eine solche Funktionalität ziemlich einfach ist, und ich bin mir nicht sicher, ob ich etwas vermisse, oder es gibt eine andere Möglichkeit, dieses Problem anzugehen (Regex oder etwas?).

Dank

Antwort

5

Die EdgeNgramField Feld mit getan werden könnte:

some_field = indexes.EdgeNgramField() # also prepare value for this field or use model_attr 

Dann gilt für teilweise Übereinstimmung:

SearchQuerySet().all().filter(some_field='ear') 
+3

Thank you! Deine Antwort ist nicht 100% richtig, aber sie führt mich in die richtige Richtung. Die Lösung war, das ** NgramField **, nicht das ** EdgeNgramField **, wie folgt zu verwenden: 'some_field = indexes.NgramField (model_attr = 'some_field')'. Das ** EdgeNgramField ** kann nur _ "beginnt mit" _ und _ "endet mit" _ Art der Filterung. – Nahn

+0

Ich arbeitete nicht mit Solr, aber benutze ** NgramField ** arbeitete für mich mit ElastiSearch. –

+1

EdgeNgram Feld funktioniert nicht wie '__contains', es funktioniert durch Stemmen und Finden anderer Übereinstimmungen basierend auf den Stämmen, daher wird es zu einem viel mehr unscharfen Resultset führen als es enthält. – shredding

0

Es ist ein Fehler im Heuhaufen.

Wie Sie gesagt haben, __exact ist genau wie __contains implementiert und daher diese Funktionalität nicht out of the box im Heuhaufen existiert.

Das Update wartet hier verschmelzen: https://github.com/django-haystack/django-haystack/issues/1041

Sie können die Wartezeit für einen festen Release wie diese Brücke:

from haystack.inputs import BaseInput, Clean 


class CustomContain(BaseInput): 
    """ 
    An input type for making wildcard matches. 
    """ 
    input_type_name = 'custom_contain' 

    def prepare(self, query_obj): 
     query_string = super(CustomContain, self).prepare(query_obj) 
     query_string = query_obj.clean(query_string) 

     exact_bits = [Clean(bit).prepare(query_obj) for bit in query_string.split(' ') if bit] 
     query_string = u' '.join(exact_bits) 

     return u'*{}*'.format(query_string) 

# Usage: 
SearchQuerySet().filter(content=CustomContain('searchcontentgoeshere')) 
Verwandte Themen