2

バックエンドとして Whoosh 2.4.1 を使用し、Haystack 1.2.7 を使用して約 9,000 のドキュメントをインデックス化しています。Haystack を使用しているにもかかわらず、それはシューシュの問題のように見えます。私のデバッグケースを見てください:

1) 正確なルックアップを実行すると、Whoosh はドキュメントを見つけます (以下のように):

>>> SearchQuerySet().all().models(PedidoSaida).filter(numero__exact='6210202443/10')
[<SearchResult: logistica.pedidosaida (pk=u'6')>]

2) startswith ルックアップを実行しただけでは、Whoosh はドキュメントを見つけられません (以下のように):

>>> SearchQuerySet().all().models(PedidoSaida).filter(numero__startswith='6210202443/10')
[]

3) すべてを 1 つの OR クエリにまとめても、Whoosh はまだドキュメントを見つけられません (以下のように):

>>> SearchQuerySet().all().models(PedidoSaida).filter(SQ(numero__exact='6210202443/10') | SQ(numero__startswith='6210202443/10'))
[]

Haystack が Whoosh に送信するクエリを調べると、次のようになります。

>>> str(SearchQuerySet().all().models(PedidoSaida).filter(numero__exact='6210202443/10').query)                                       
'(numero:6210202443/10) AND (django_ct:logistica.pedidosaida)'

>>> str(SearchQuerySet().all().models(PedidoSaida).filter(numero__startswith='6210202443/10').query)
'(numero:6210202443/10*) AND (django_ct:logistica.pedidosaida)'

>>> str(SearchQuerySet().all().models(PedidoSaida).filter(SQ(numero__exact='6210202443/10') | SQ(numero__startswith='6210202443/10')).query)
'((numero:6210202443/10 OR numero:6210202443/10*)) AND (django_ct:logistica.pedidosaida)'

ご覧のとおり、最後のクエリは正確に (最初または 2 番目) です。Whoosh が私のドキュメントを見つけてはいけませんか? ロジックのどこが間違っているのかわかりません。OR を使用していますが、ステートメントの 1 つを使用した場合よりも結果が少なくなります。

また、Whoosh が最初のクエリ (numero:6210202443/10) でドキュメントを検索し、2 番目のクエリ (numero:6210202443/10*) では検索しないのも奇妙だと思います。しかし、Haystack が私の CharField で使用する StemmingAnalyzer と関係があると思います。この後、深く考察していきます。

4

2 に答える 2

1

を直接使用して、QueryParserWhoosh がそのクエリをどのように解析しているかを確認できます。

>>> from whoosh.qparser import QueryParser
>>> QueryParser("content", schema=None).parse('((numero:6210202443/10 OR numero:6210202443/10*)) AND (django_ct:logistica.pedidosaida)')
And([Or([Term('numero', '6210202443/10'), Term('numero', '6210202443/')]), Prefix('content', '10'), Term('django_ct', 'logistica.pedidosaida')])

最後の行を再フォーマットしましょう:

And([
    Or([
        Term('numero', '6210202443/10'),
        Term('numero', '6210202443/'),
    ]),
    Prefix('content', '10'),
    Term('django_ct', 'logistica.pedidosaida'),
])

つまり、検索用語*よりも強く結合しているように見えます。/確かに、これをシューッという音のバグとして議論することができました。(メンテナーはあなたのパッチを気に入ると確信しています☺)

頭に浮かぶ回避策:

  1. Whoosh のあいまいに定義された人間指向のクエリ言語を往復するのではなく、自分でクエリを作成します。もちろん、これはインデックスが同じマシン上にあり、同じプロセスで読み取っている場合にのみ機能します。ヘイスタックについてはよくわかりません。

  2. numeroフィールドでスラッシュを使用しないでください。アンダースコアなど、クエリ構文のように見えにくいものに変更します。

  3. プレフィックス検索を行うときは、スラッシュを含めないでください。たとえば、6210202443*クエリのどこでも問題なく機能します。

于 2013-02-28T01:04:58.963 に答える
0

@Eevee のアイデアに従って、いくつかのテストを行いました。これを確認してください:

>>> QueryParser("content", schema=None).parse('((numero:6210202443/10 OR (numero:6210202443/10*))) AND (django_ct:logistica.pedidosaida)')
And([
    Or([
        Term('numero', '6210202443/10'), 
        And([
            Term('numero', '6210202443/'), 
            Prefix('content', '10')
        ])
    ]), 
    Term('django_ct', 'logistica.pedidosaida')
])

/より優先されるようですOR。それは理にかなっていますか?論理演算子は最優先すべきだと思います。同意しますか?

この動作が私が推測するよりも正しい場合、それは Haystack クエリ ジェネレーターのバグです。ではない?

パッチで貢献したいのですが、それが本当にパーサーのバグなのかどうかわかりません。より意味のある優先順位に依存します。

于 2013-03-01T02:06:36.973 に答える