rebuild_index
从一个 Python shell 会话多次运行该命令时,我注意到奇怪的行为。
在此示例中,我rebuild_index
从 Bash shell 运行,然后进入 Python shell 以检查构面值。它们是大写的。然后我rebuild_index
从 Python shell 运行命令,并且构面值是小写的。
$ 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': {}}
下一个奇怪的事情是,如果我rebuild_index
从 Python shell 运行命令并尝试按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 再次标记值。这解释了为什么以小写形式返回构面值。它还解释了我在尝试对结果进行排序时收到的错误消息:“无法对每个文档具有多个值或每个字段多个标记的字符串类型进行排序”。它必须将name
空格字符的值分解为多个值。
现在问题来了,如果我rebuild_index
在 Python 解释器中运行不止一次,为什么对 Haystack 很重要?我不明白这一点,因为rebuild_index
它也clear_index
作为第一个操作运行。清除索引不应该是确保再次重建索引获得相同结果的充分方法吗?显然这不是真的。我不知道为什么。
这里真正的困境是,如果我不能 1) 以原始格式检索构面值,我到底应该如何编写正确的单元测试(在哪里rebuild_index
运行)?setUp()
2) 我不能按具有空格值的字段排序?
有什么解释、建议或想法吗?