rebuild_index
1 つの Python シェル セッションからコマンドを複数回実行すると、奇妙な動作に気付きます。
この例ではrebuild_index
、Bash シェルから実行し、Python シェルに入ってファセット値を確認しました。それらは大文字です。次にrebuild_index
、Python シェルからコマンドを実行しましたが、ファセット値は小文字でした。
$ 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 シェルからコマンドを実行して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 シェルを終了しました。別の Python シェルを開始しました。次の行を実行しましたが、結果は正しかったです。
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 インタープリターの存続期間中に 1 回だけ正常に実行できるという結論に達しました。Python インタープリターでもう一度実行すると、Haystack によって値が再度トークン化されるようです。これは、ファセット値が小文字で返された理由を説明しています。また、結果を並べ替えようとしたときに表示されたエラー メッセージについても説明しています。name
スペース文字で値を複数の値に分割する必要があります。
ここで質問rebuild_index
です。Python インタープリターで複数回実行すると、Haystack にとって問題になるのはなぜですか? 最初の操作としてrebuild_index
も実行されるため、これはわかりません。clear_index
インデックスをクリアすることは、インデックスを再構築しても同じ結果が得られることを確認するのに十分な方法ではないでしょうか? どうやらこれは真実ではありません。理由がわかりません。
ここでの本当のジレンマは、1) ファセット値を元のフォーマットで取得できない場合、一体どのようにして適切な単体テスト (でrebuild_index
実行される場所) を作成する必要があるかということです。setUp()
2) スペースを含む値を持つフィールドで注文できませんか?
説明、提案、またはアイデアはありますか?