2

У меня возникли проблемы с получением django для автоматического индексирования вновь созданных объектов.Индексирование нового объекта с помощью Django & Elasticsearch

Я использовал groupby для создания пользовательских данных.

Каждый раз, когда создается новая модель, она должна индексировать ее.

Это делает индексирует значение «title», но значения «тега» нет.

Итак, я создал ручную функцию «manual_index». Когда я запускаю это, значение «тега» делает, добавляется в индекс. Однако этот процесс должен запускаться вручную.

Как я могу получить значение «тег» для сохранения каждый раз, когда создается новый объект?

Я использую elasticsearch_dsl

Search.py ​​

class TaskIndex(DocType): 
    title = String() 
    class Meta: 
     index = 'task-index' 

def manual_index(): 
    TaskIndex.init() 
    es = Elasticsearch() 
    bulk(client=es, actions=(b.indexing() for b in models.Task.objects.all().iterator())) 

Models.py

from itertools import groupby 

class Tag(models.Model): 
    name = models.CharField("Name", max_length=5000, blank=True) 
    taglevel = models.IntegerField("Tag level", null=True, blank=True) 

class Item(models.Model): 
    title = models.CharField("Title", max_length=10000, blank=True) 
    tag = models.ManyToManyField('Tag', blank=True) 

    def get_grouped_tags(self): 
     tag = self.tag.order_by('taglevel') 
     grouped_tags = { 
      tag_level: [ 
       { 'name': tag_of_level.name, 'taglevel': tag_of_level.taglevel, } 
       for tag_of_level in tags_of_level 
      ] for tag_level, tags_of_level 
      in groupby(tag, lambda tag: tag.taglevel) 
     } 
     return grouped_tags 

    def indexing(self): 
     obj = TaskIndex(
      meta={'id': self.id}, 
      title=self.title, 
      tag=self.get_grouped_tags() 
     obj.save() 
     return obj.to_dict(include_meta=True) 

ответ

0

Есть несколько вопросов здесь, в первую очередь вы спасаете все дважды - один раз в indexing (по телефону .save()), а затем в manual_index.

Код в manual_index более эффективен и определенно должен быть вокруг для переиндексации всего набора данных. Для создания отдельной модели вы можете просто использовать метод indexing почти так же, как и использовать фреймворк django signal. Просто измените метод indexing вернуть TaskIndex объект и добавить эквивалент следующего кода в models.py (без вызова .save() на него!): https://github.com/HonzaKral/es-django-example/blob/master/qa/models.py#L128-L137

В своем коде вы будете использовать только indexing вместо моего to_search.

Надеется, что это помогает, Хонза

+0

Ой, извините, я проглядел свой комментарий о 'tag' объекта. Проблема в том, что на стороне Django «индексирование» запускается до сохранения многих-многих данных. Есть несколько способов обойти это, безопаснее также использовать сигнал 'm2m_changed' - https://docs.djangoproject.com/en/1.10/ref/signals/#m2m-changed –