Django haystack, priority for some fields in search

I have a model like this:

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

I want to search a string in the fields of this model. Suppose these instances of MyModel:

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

when I search for "you", he must show me the first and second copies. finally, I need to show results that โ€œyouโ€ in desc1 are higher than others. for example, in this sample, the second should be higher than the first.

I used hay to search and created a template for this. but I could not solve the priority problem.

+6
source share
2 answers

When you say โ€œpriority,โ€ you really mean โ€œsorting,โ€ in search ling.

Django Haystack can sort by field matches, but he can sort by 'score', where he uses an algorithm to determine the sort order. You can influence weighting scores with "Boost'ing it" - see http://django-haystack.readthedocs.org/en/latest/boost.html

In addition, you should consider adding additional fields to search_indexes.py, which will be for weighting only. You do not need to have a one-to-one mapping between the fields of the Django model and the index. Sort of

 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 
+2
source

I use this approach.

 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 
+1
source

Source: https://habr.com/ru/post/915423/


All Articles