2012-05-10 54 views
6

一些領域我有這樣一個模型:Django的草垛,優先在搜索

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中「you」的結果高於其他結果。例如,在這個樣本中,第二個應該比第一個高。

我已經使用乾草堆進行搜索併爲此創建了一個模板。但我無法解決優先問題。

回答

2

當你說'優先',你真的是指'排序',在搜索的術語。

Django Haystack可以按字段匹配進行排序,但它可以按'分數'排序,它使用算法確定排序順序。您可以通過'提升'來影響分數的權重 - 請參閱 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

「boosting」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