不止一次运行rebuild_index命令看起来像是再次标记值

时间:2012-08-31 05:02:23

标签: python django django-haystack

在一个Python shell会话中多次运行rebuild_index命令时,我注意到了奇怪的行为。

在此示例中,我从Bash shell运行rebuild_index,然后进入Python shell以检查构面值。他们是资本化的。然后我从Python shell运行rebuild_index命令,facet值为小写。

$ bin/manage rebuild_index
WARNING: This will irreparably remove EVERYTHING from your search index in connection 'default'.
Your choices after this are to restore from backups or rebuild via the `rebuild_index` command.
Are you sure you wish to continue? [y/N] y

Removing all documents from your index because you said so.
Failed to clear Elasticsearch index: Non-OK status code returned (404) containing u'IndexMissingException[[my_index] missing]'.
All documents removed.
Indexing 40 components.


In [1]: from haystack.query import SearchQuerySet

In [2]: SearchQuerySet().models(Component).facet('primary_language').facet_counts()
Out[2]:
{'dates': {},
 'fields': {'primary_language': [(u'Java', 24),
   (u'Scala', 5),
   (u'C', 3),
   (u'Python', 2),
   (u'C++', 2),
   (u'PHP', 1),
   (u'Javascript', 1),
   (u'Ada', 1),
   (u'.Net', 1)]},
 'queries': {}}

In [3]: from django.core import management

In [4]: management.call_command('rebuild_index', interactive=False, verbosity=0)
Failed to clear Elasticsearch index: Non-OK status code returned (404) containing u'IndexMissingException[[my_index] missing]'.

In [5]: SearchQuerySet().models(Component).facet('primary_language').facet_counts()
Out[5]:
{'dates': {},
 'fields': {'primary_language': [(u'java', 24),
   (u'scala', 5),
   (u'c', 5),
   (u'python', 2),
   (u'php', 1),
   (u'net', 1),
   (u'javascript', 1),
   (u'ada', 1)]},
 'queries': {}}

下一个奇怪的事情是,如果我从Python shell运行rebuild_index命令并尝试按name字段排序,我会收到ElasticSearch错误。

$ bin/manage rebuild_index
WARNING: This will irreparably remove EVERYTHING from your search index in connection 'default'.
Your choices after this are to restore from backups or rebuild via the `rebuild_index` command.
Are you sure you wish to continue? [y/N] y

Removing all documents from your index because you said so.
Failed to clear Elasticsearch index: Non-OK status code returned (404) containing u'IndexMissingException[[my_index] missing]'.
All documents removed.
Indexing 40 components.


In [1]: from haystack.query import SearchQuerySet

In [2]: SearchQuerySet().order_by('name')
Out[2]: [<SearchResult: my_app.component (pk=u'2')>, <SearchResult: my_app.component (pk=u'1')>, <SearchResult: my_app.component (pk=u'5')>, <SearchResult: my_app.component (pk=u'4')>, <SearchResult: my_app.component (pk=u'3')>, <SearchResult: my_app.component (pk=u'6')>, <SearchResult: my_app.component (pk=u'7')>, <SearchResult: my_app.component (pk=u'8')>, <SearchResult: my_app.component (pk=u'9')>, <SearchResult: my_app.component (pk=u'11')>, <SearchResult: my_app.component (pk=u'14')>, <SearchResult: my_app.component (pk=u'13')>, <SearchResult: my_app.component (pk=u'15')>, <SearchResult: my_app.component (pk=u'19')>, <SearchResult: my_app.component (pk=u'20')>, <SearchResult: my_app.component (pk=u'21')>, <SearchResult: my_app.component (pk=u'22')>, <SearchResult: my_app.component (pk=u'23')>, <SearchResult: my_app.component (pk=u'24')>, '...(remaining elements truncated)...']

In [3]: from django.core import management

In [4]: management.call_command('rebuild_index', interactive=False, verbosity=0)
Failed to clear Elasticsearch index: Non-OK status code returned (404) containing u'IndexMissingException[[my_index] missing]'.

In [5]: SearchQuerySet().order_by('name')
Failed to query Elasticsearch using '*:*': Non-OK status code returned (500) containing u'SearchPhaseExecutionException[Failed to execute phase [query], total failure; shardFailures {[SkgxFvdjRgyoiHv2qSpfbQ][my_index][4]: QueryPhaseExecutionException[[my_index][4]: query[filtered(ConstantScore(NotDeleted(cache(QueryWrapperFilter(django_ct:my_app.component)))))->cache(_type:modelresult)],from[0],size[20],sort[<custom:"name": org.elasticsearch.index.field.data.strings.StringFieldDataType$1@3cb9b947>]: Query Failed [Failed to execute main query]]; nested: IOException[Can\'t sort on string types with more than one value per doc, or more than one token per field]; }{[SkgxFvdjRgyoiHv2qSpfbQ][my_index][0]: QueryPhaseExecutionException[[my_index][0]: query[filtered(ConstantScore(NotDeleted(cache(QueryWrapperFilter(django_ct:my_app.component)))))->cache(_type:modelresult)],from[0],size[20],sort[<custom:"name": org.elasticsearch.index.field.data.strings.StringFieldDataType$1@249cf580>]: Query Failed [Failed to execute main query]]; nested: IOException[Can\'t sort on string types with more than one value per doc, or more than one token per field]; }{[SkgxFvdjRgyoiHv2qSpfbQ][my_index][3]: QueryPhaseExecutionException[[my_index][3]: query[filtered(ConstantScore(NotDeleted(cache(QueryWrapperFilter(django_ct:my_app.component)))))->cache(_type:modelresult)],from[0],size[20],sort[<custom:"name": org.elasticsearch.index.field.data.strings.StringFieldDataType$1@4ff80724>]: Query Failed [Failed to execute main query]]; nested: IOException[Can\'t sort on string types with more than one value per doc, or more than one token per field]; }{[SkgxFvdjRgyoiHv2qSpfbQ][my_index][2]: QueryPhaseExecutionException[[my_index][2]: query[filtered(ConstantScore(NotDeleted(cache(QueryWrapperFilter(django_ct:my_app.component)))))->cache(_type:modelresult)],from[0],size[20],sort[<custom:"name": org.elasticsearch.index.field.data.strings.StringFieldDataType$1@99b8b51>]: Query Failed [Failed to execute main query]]; nested: IOException[Can\'t sort on string types with more than one value per doc, or more than one token per field]; }{[SkgxFvdjRgyoiHv2qSpfbQ][my_index][1]: QueryPhaseExecutionException[[my_index][1]: query[filtered(ConstantScore(NotDeleted(cache(QueryWrapperFilter(django_ct:my_app.component)))))->cache(_type:modelresult)],from[0],size[20],sort[<custom:"name": org.elasticsearch.index.field.data.strings.StringFieldDataType$1@42d777c4>]: Query Failed [Failed to execute main query]]; nested: IOException[Can\'t sort on string types with more than one value per doc, or more than one token per field]; }]'.
Out[5]: []

在此之后我退出了Python shell。我开始了另一个Python shell。我跑了以下几行,结果是正确的。

from django.core import management
management.call_command('rebuild_index', interactive=False, verbosity=0)
from haystack.query import SearchQuerySet
SearchQuerySet().order_by('name')

这使我得出结论:rebuild_index只能在Python解释器的生命周期内成功运行一次。看起来在Python解释器中第二次运行它会使Haystack再次对值进行标记。这解释了为什么facet值以小写形式返回。它还解释了我在尝试对结果进行排序时收到的错误消息:“无法对每个文档具有多个值的字符串类型进行排序,或者每个字段使用多个标记”。它必须将空格字符的name值分解为多个值。

现在问题是,如果我在Python解释器中不止一次运行rebuild_index,为什么对Haystack很重要?我不明白这一点,因为rebuild_index也运行clear_index作为第一个操作。不应该清除索引是一种足够的方法来确保重建索引会让你获得同样的东西吗?显然这不是真的。我不明白为什么。

这里真正的困境是,如果我不能,我应该如何编写适当的单元测试(rebuild_index中运行setUp()) 1)以原始格式检索构面值? 2)我不能通过具有空格值的字段进行排序?

任何解释,建议或想法?

1 个答案:

答案 0 :(得分:1)

这是因为需要在第二次运行rebuild_index之前重置后端中的实例变量。

from django.core import management
from haystack import connections
backend = connections['default'].get_backend()
backend.setup_complete = False
backend.existing_mapping = None
management.call_command('rebuild_index', interactive=False, verbosity=0)