6

ブール値で SearchQuerySet をフィルタリングしようとしてもうまくいきません。(テスト中は、提供されている「シンプルな」バックエンド検索エンジンを使用しています。)

次のようなインデックスがあります。

class MyIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    has_been_sent = indexes.BooleanField(model_attr='has_been_sent')
    # other fields

    def get_model(self):
        return MyModel

そして、検索にカスタム フォームを使用します。

BOOLEAN_OPTIONS = [ ('either', 'Either'), ('yes', 'Yes'), ('no', 'No') ]

class MyModelSearchForm(SearchForm):
    # other fields
    has_been_sent = forms.ChoiceField( widget = forms.Select(), label = 'Sent?', choices=BOOLEAN_OPTIONS )

def search(self):
    sqs = super(MyModelSearchForm, self).search()

    if not self.is_valid(): return self.no_query_found()

    sqs = sqs.models(MyModel) # cuts out other models from the search results
    if self.cleaned_data['has_been_sent'] != 'either':
        if self.cleaned_data['has_been_sent'] == 'yes': sent = True
        else: sent = False
        sqs = sqs.filter(has_been_sent=sent)

    return sqs

フォームで has_been_sent オプションを Yes または No に設定すると、常に結果が 0 になります。これは明らかに間違っています。私もシェルで試しましたが、うまくいきませんでした。どちらも空のリストを返しsqs.filter(has_been_sent=True)ますが、has_been_sent の値が True の一連のレコードを明確に示しています。さらに奇妙なことに、「f」、「a」、および「j」などの無関係な文字とともに、レコードのサブセットを返します! 私は完全に途方に暮れています。Haystack でこの種の問題を経験した人はいますか?sqs.filter(has_been_sent=False)sqs.values('has_been_sent')sqs.filter(has_been_sent='t')

関連するメモとしてSearchQuerySet().filter()、インデックス フィールド (search_indexes.py 内) またはモデル フィールド (それぞれの models.py 内) からフィルタリングするフィールドはありますか?

編集:

Django の manage.py シェルを使用してフィルターをテストしようとしましたが、間違っていると思います。index_queryset() メソッドを使用して MyModel のサブセットに制限したため、search_indexes.py に従っているようには見えませんが、シェルで MyModel のすべてのオブジェクトを取得します。

>>> from haystack.query import SearchQuerySet
>>> from myapp.models import MyModel
>>> sqs = SearchQuerySet().models(MyModel)

そして、いくつかのテスト:

>>> len(sqs) # SHOULD be 5, due to the index_queryset() method I defined in search_indexes.py
17794
>>> sqs.filter(has_been_sent='true') # Same happens for True, 'TRUE', and all forms of false
[]
>>> len(sqs.filter(not_a_real_field='g')) # Made-up filter field, returns a subset somehow??
2591
>>> len(sqs.filter(has_been_sent='t'))
3621
>>> len(sqs.filter(has_been_sent='f'))
2812

偽のフィールドでフィルタリングするとサブセットが取得されるため、has_been_sent がフィルター フィールドの 1 つとして認識されていないと思います。特に、't' と 'f' の結果は、すべてのレコードにブール値フィールドが必要なため、合計する必要がある合計に達しないためです。テストのステップが抜けていませんか?

4

2 に答える 2

7

true文字列として、またはクエリでフィルタリングしてみてくださいfalse。これは干し草スタックの既知の制限であり、これが修正されているかどうかはわかりません。

sqs.filter(has_been_sent=True)

これを行う:

sqs.filter(has_been_sent='true') # true or false in lowercase

PSファイルSearchQuerySet().filter()で定義されたフィールドに基づいてフィルタリングする場合。search_indexes.py

于 2013-10-07T21:19:44.853 に答える
1

問題は Simple バックエンドにあったようです。Haystack をインストールして Whoosh に切り替えたところ、この問題は解消されました。(現在、SearchQuerySet().models() は機能しませんが、これは明らかに、Haystack + Whoosh のバグとして文書化されています。)

編集: Whoosh でさらに問題が発生したため、バックエンドとして Solr 4.5.1 の使用に切り替えました。現在、すべてが期待どおりに機能しています。

于 2013-10-08T18:55:24.977 に答える