【问题标题】:Django Haystack update index fasterDjango Haystack 更新索引更快
【发布时间】:2012-11-28 22:32:51
【问题描述】:

我使用 Django Haystack 已经有一段时间了,它很棒!我有一个相当繁重的网站,其中的数据需要不时更新(15 到 30 分钟)。

使用python manage.py update_index 时,更新数据需要很长时间。有没有办法加快这个速度?或者,如果可能,可能只更新更改的数据..

我目前正在使用 Django Haystack 1.2.7 和 Solr 作为后端和 Django 1.4。

谢谢!!!


编辑:

是的,我已经尝试阅读文档的那一部分,但我真正需要的是一种加快索引速度的方法。也许只更新最近的数据而不是全部更新。我找到了get_updated_field,但不知道如何使用它。在文档中只提到了使用它的原因,但没有显示实际示例。


编辑 2:

start = DateTimeField(model_attr='start', null=True, faceted=True, --HERE?--)

编辑 3:

好的,我已经实现了下面的解决方案,但是当我尝试重建索引(包含 45000 个数据)时,它几乎让我的计算机崩溃了。等待10分钟后出现错误:

 File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 443, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 382, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 196, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 232, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python2.7/dist-packages/haystack/management/commands/rebuild_index.py", line 16, in handle
    call_command('update_index', **options)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 150, in call_command
    return klass.execute(*args, **defaults)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 232, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python2.7/dist-packages/haystack/management/commands/update_index.py", line 193, in handle
    return super(Command, self).handle(*apps, **options)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 304, in handle
    app_output = self.handle_app(app, **options)
  File "/usr/local/lib/python2.7/dist-packages/haystack/management/commands/update_index.py", line 229, in handle_app
    do_update(index, qs, start, end, total, self.verbosity)
  File "/usr/local/lib/python2.7/dist-packages/haystack/management/commands/update_index.py", line 109, in do_update
    index.backend.update(index, current_qs)
  File "/usr/local/lib/python2.7/dist-packages/haystack/backends/solr_backend.py", line 73, in update
    self.conn.add(docs, commit=commit, boost=index.get_field_weights())
  File "/usr/local/lib/python2.7/dist-packages/pysolr.py", line 686, in add
    m = ET.tostring(message, encoding='utf-8')
  File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1127, in tostring
    ElementTree(element).write(file, encoding, method=method)
  File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 821, in write
    serialize(write, self._root, encoding, qnames, namespaces)
  File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 940, in _serialize_xml
    _serialize_xml(write, e, encoding, qnames, None)
  File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 940, in _serialize_xml
    _serialize_xml(write, e, encoding, qnames, None)
  File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 915, in _serialize_xml
    write("<" + tag)
MemoryError

【问题讨论】:

标签: django solr django-haystack


【解决方案1】:

get_updated_field 应返回一个字符串,该字符串包含模型上的属性名称,其中包含模型更新的日期 (haystack docs)。具有 auto_now=True 的 DateField 将是理想的选择 (Django docs)。

例如,我的 UserProfile 模型有一个名为 updated 的字段

models.py

class UserProfile(models.Model):
    user = models.ForeignKey(User)
    # lots of other fields snipped
    updated = models.DateTimeField(auto_now=True)

search_indexes.py

class UserProfileIndex(SearchIndex):
    text = CharField(document=True, use_template=True)
    user = CharField(model_attr='user')
    user_fullname = CharField(model_attr='user__get_full_name')

    def get_model(self):
        return UserProfile

    def get_updated_field(self):
        return "updated"

然后,当我运行 ./manage.py update_index --age=10 时,它只会索引过去 10 小时内更新的用户配置文件。

【讨论】:

  • 我应该在 search_indexes.py 的哪里添加 auto_now=True?我在上面的问题中做了一个例子。还有我应该在哪里实现get_updated_field。谢谢你的回答!!
  • auto_now 会放在models.py 中的Model 上,函数get_updated_field 会放在SearchIndex 类中。
  • 你的解决方案会起作用我对此毫无疑问..但是当我运行rebuild_index时出现错误..
  • 如果您的搜索索引模型引用了索引中的其他模型,请小心。最后更新的内容在更改时不会更改,然后它们不会索引(想象主对象上的类别模型)
  • 仅供参考,如果您使用 Django 的 QuerySet 方法进行批量更新 .update(),则不会使用 auto_now 功能,因为不会触发 post_save 信号。这意味着上面的--age 选项不能仅更新最近更改的模型。要解决这个问题,您可以循环查询集并使用.save(),或者继续使用.update(),您只需要自己手动更新时间,例如updated=datetime.datetime.now().
猜你喜欢
  • 1970-01-01
  • 2011-05-20
  • 2018-07-06
  • 1970-01-01
  • 2023-03-27
  • 2012-01-19
  • 2012-03-21
  • 2015-11-02
  • 1970-01-01
相关资源
最近更新 更多