2012-05-10 4 views
6

У меня есть модель, как это:Джанго стог, приоритет для некоторых полей в поисках

class MyModel(models.Model): 
    desc1 = models.TextField(blank=True, default="") 
    desc2 = models.TextField(blank=True, default="") 

Я хочу искать строку на полях этой модели. Пусть эти экземпляры MyModel:

1: desc1="ABc?", desc2="asdasd you" 
2: desc1="Hello, How are you?", desc2="Thank you!" 
3: desc1="ABc?", desc2="ajdf" 

когда я ищу «вы», он должен показать мне, первый и второй экземпляры. Наконец-то мне нужно показать результаты, которые «вы» в desc1 выше других. например, в этом образце, второй должен быть выше первого.

Я использовал, haystack для поиска и создал шаблон для этого. но я не мог решить приоритетную проблему.

ответ

2

Когда вы говорите «приоритет», вы действительно имеете в виду «сортировку», в процессе поиска.

Django Haystack может сортировать по полям, но может сортировать по 'score', где использует алгоритм для определения порядка сортировки. Вы можете влиять на вес оценки с помощью «Boost'ing it» - см. http://django-haystack.readthedocs.org/en/latest/boost.html

Кроме того, вам следует рассмотреть возможность добавления дополнительных полей в search_indexes.py, которые будут только для взвешивания. Вам не нужно иметь сопоставление «один к одному» между полями модели Django и индексом. Что-то вроде

class MyModelIndex(QueuedSearchIndex): 
    desc1 = indexes.CharField() 
    desc2 = indexes.CharField() 
    otherWeightedField = indexes.CharField() 

    def prepare_otherWeightedField(self,obj) 
     # fill the extra field with extra stuff to help you sort, based on processing values from other fields 
+0

«Повышающий» API выглядит очень неустойчивым. Документ, к которому вы ссылаетесь, показывает совершенно другой подход ... который даже не работает с текущим кодом ... – Cerin

+0

Чтобы быть понятным, это пример, который был написан для Haystack 1.2 –

1

Я использую этот подход.

from types import ListType 
from haystack import indexes 


class DocumentField(indexes.SearchField): 
    """An index field that combines and weights other fields because Haystack 
    does not provide for weighted searching. This field makes use of other 
    existing field classes for DRY.""" 

    def __init__(self, *args, **kwargs): 
     self.fields = kwargs.pop("fields", None) 
     super(DocumentField, self).__init__(*args, **kwargs) 
     self.document = True 
     self.use_template = False 

    def prepare(self, obj): 
     values = [] 

     for field_instance in self.fields.values(): 
      v = field_instance.prepare(obj) 
      if not v: 
       continue 
      if not isinstance(v, ListType): 
       v = [v] 
      # Apply boost 
      v = v * int(field_instance.boost * 10) 
      values.extend(v) 

     return "\n".join(values) 


class MyModelIndex(indexes.SearchIndex, indexes.Indexable): 
    text = DocumentField(fields=dict(
     desc1 = indexes.CharField(model_attr="desc1", boost=1.0), 
     desc2 = indexes.CharField(model_attr="desc2", boost=0.7) 
    )) 

    def get_model(self): 
     return MyModel 
+0

. Удивительно, что никто не пытается реализовать это. Я полагаю, что это все равно не применимо, если мы хотим смешать EdgeNgramField и CharField? Я думаю о просто изменении набора запросов, чтобы поиск по умолчанию выполнялся в разных полях – Forethinker

Смежные вопросы