2013-10-07 13 views
6

SearchQuerySetをブール値でフィルタリングしようとしても、私にとっては効果がありません。 (テストの間、私は提供された「シンプル」バックエンドの検索エンジンを使用しています。)Django Haystack - 検索結果をブール値フィールドでフィルタリングするにはどうすればよいですか?

は、私は次のようにインデックスを持っている:

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)sqs.filter(has_been_sent=False)は両方とも空のリストを返します。また、sqs.values('has_been_sent')はhas_been_sentのTrue値を持つレコードの束を明確に示しています。そして、見知らぬ人でも、sqs.filter(has_been_sent='t')は 'f'、 'a'、 'j'のような無関係な文字とともに、レコードのサブセットを返します!私は完全な損失にあります。誰もがこの種のHaystackの問題を経験していますか?関連ノートで

、あなたはインデックスフィールド(search_indexes.py中)または(それぞれのmodels.pyで)モデルフィールドからSearchQuerySet().filter()経由でフィルタリングするフィールドですか?

EDIT:

私は、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を認識しないと思います。特に、 't'と 'f'の結果は、合計値に加算されないので、すべてのレコードにそのブール値フィールドが必要であるため、SHOULDである必要があります。私のテストで一歩も欠けていますか?

答えて

1

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

編集:Whooshのさらなる問題のため、私はSolr 4.5.1をバックエンドとして使用しました。すべてが今期待どおりに動作しています。

6

これは干し草の山で既知の制限されていると私は、これは固定されている場合わからない、代わりに行うので、クエリ内の文字列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ファイルで定義されたフィールドに基づいてフィルタリングします。

+0

Hmm。私はまだ「真実」と「偽」という空の結果を得ています。私は間違ってmanage.pyシェルを通してテストしなければならないと思う。メイン・ポストを編集して、私がどのようにテストしているかを示しました。私は一歩足りなかったに違いないと思う。 – Goluxas

+0

ブールフィールドのデフォルト値をモデルまたは 'search_indexes.py'ファイルに追加してから、rebuild_indexとupdate_indexにコマンドを実行して、私が示唆したように再度テストすることをお勧めします。 –

関連する問題