2015-02-26 2 views
2

Я установил на своем сайте индекс поиска, используя django-haystack + elasticsearch. Существуют разные индексы, и в целом они работают правильно, за исключением ProjectIndex, когда я ищу Person. Поясню:django-haystack elasticsearch несколько индексов неверные результаты

Те модели:

class Person(models.Model): 
    first_name = models.CharField() 
    last_name = models.CharField() 

class Project(models.Model): 
    project_name = models.CharField() 
    employees = models.ManyToManyField(Person) 

И те показатели:

class ProjectIndex(indexes.SearchIndex, indexes.Indexable): 
    text = indexes.EdgeNgramField(document=True, use_template=True) 
    project_name = indexes.CharField(model_attr='project_name', boost=1.4) 
    employees = indexes.CharField(boost=1.5) 

    def get_model(self): 
     return Project 

    def prepare_employees(self, obj): 
     return ' '.join([employee.__unicode__() for employee in obj.employees.all()]) 

    def prepare(self, obj): 
     data = super(ProjectIndex, self).prepare(obj) 
     data['boost'] = 1.3 
     return data 

class PersonIndex(indexes.SearchIndex, indexes.Indexable): 
    text = indexes.EdgeNgramField(document=True, use_template=True) 
    first_name = indexes.CharField(model_attr='first_name', boost=1.1) 
    last_name = indexes.CharField(model_attr='last_name', boost=1.2) 

    def get_model(self): 
     return Person 

Когда я бегу rebuild_index все проекты, кажется, правильно проиндексированы. Простой HTTP-запрос к серверу elasticsearch при поиске человека возвращает полезные результаты проекта (действительно значимый).

>>> from urllib import urlopen 
>>> response = urlopen('http://127.0.0.1:9200/_search?q=' + q) 
>>> json_data = response.read() 
>>> from json import loads 
>>> d = loads(json_data) 
>>> f = filter(lambda d: d['_source']['django_ct'] == "project.project", d['hits']['hits']) 
>>> len(f) 
8 

С другой стороны, SearchQuerySet возвращается всего 3 проектов, в которых этот человек не участвует, ни это имя лица, похоже на название проекта.

>>> sqs = SearchQuerySet().filter(content__auto=q) 
>>> sqs.count() 
8 
>>> sqs.models(Project) 
[<SearchResult: project.project (pk=u'409')>, <SearchResult: project.project (pk=u'521')>, <SearchResult: project.project (pk=u'82')>] 

Я делаю что-то не так здесь? Спасибо за ваши отзывы :-)

ответ

0

Мне удалось получить гораздо более качественные результаты, изменив мой запрос filter(). Я узнал о документации django-haystack о методе filter_or(), который можно объединить столько раз, сколько необходимо. Таким образом, легко сопоставить столько полей и/или индексов, сколько необходимо. Например:

sqs = SearchQuerySet().filter_or(content__contains=q).filter_or(employees__name__contains=q).filter_or(projects_name__contains=q) 
# etc. 

Как уже было сказано, это значительно улучшило качество результатов поиска.

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