使用 Django 和 Elasticsearch 索引新对象
Posted
技术标签:
【中文标题】使用 Django 和 Elasticsearch 索引新对象【英文标题】:Indexing new object with Django & Elasticsearch 【发布时间】:2017-06-28 07:22:24 【问题描述】:我无法让 django 自动索引新创建的对象。
我使用groupby
创建了一些自定义数据。
每次创建新模型时,都应为其编制索引。
它确实索引了“title”值,但“tag”值不存在。
所以,我创建了一个手动函数“manual_index”。当我运行它时,“标签”值 确实 被添加到索引中。但是这个过程必须手动触发。
如何在每次创建新对象时获取要保存的“标记”值?
我正在使用 elasticsearch_dsl
搜索.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()))
模型.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)
【问题讨论】:
【参考方案1】:这里有几个问题,首先你要保存所有内容两次 - 一次在 indexing
中(通过调用 .save()
),然后在 manual_index
中。
manual_index
中的代码效率更高,绝对应该用于重新索引整个数据集。对于单独的模型创建,您几乎可以按原样使用indexing
方法并使用django 的signal
框架。只需修改indexing
方法以返回TaskIndex
对象(无需在其上调用.save()
!)并将以下等效代码添加到您的models.py
中:
https://github.com/HonzaKral/es-django-example/blob/master/qa/models.py#L128-L137
在您的代码中,您将只使用indexing
而不是我的to_search
。
希望这会有所帮助, 洪萨
【讨论】:
哦,抱歉,我忽略了您对tag
对象的评论。存在的问题是,在 Django 方面,indexing
在保存多对多数据之前被触发。有几种解决方法,最安全的是也使用m2m_changed
信号 - docs.djangoproject.com/en/1.10/ref/signals/#m2m-changed以上是关于使用 Django 和 Elasticsearch 索引新对象的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch:如何在 Django 中使用 Elasticsearch
Elasticsearch:如何在 Django 中使用 Elasticsearch
Django + ElasticSearch + Docker - 无论我使用啥主机名,连接超时
第15篇-使用Django进行ElasticSearch的简单方法