2013-02-28 1 views
2

У нас есть около 9k документов, индексированных с использованием Haystack 1.2.7 с Whoosh 2.4.1 в качестве бэкэнд. Несмотря на использование Haystack, это похоже на проблему Whoosh. Посмотрите на моих случаях отладки:Whoosh: не следует ИЛИ только увеличивать результаты?

1) Если я просто запустить точный поиск, Whoosh находит свой документ (как показано ниже):

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

2) Если бы я просто запустить StartsWith поиск, Свист Безразлично «т найти свой документ (как показано ниже):

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

3) Если я ставлю все вместе в одном или запросе, Свист все еще не находит мой документ (как показано ниже):

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

Взглянув в запросах, которые Стог посылает Свист, мы имеем:

>>> 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)' 

Как вы можете заметить, последний запрос в точности (первый или второй). Не стоит ли мне искать мой документ? Я не вижу, где моя логика ошибочна: я использую OR, и она находит меньше, чем когда я использую одно из операторов.

Я также считаю странным, что Whoosh находит мой документ с первым запросом (numero: 6210202443/10), но не со вторым (numero: 6210202443/10 *). Но я предполагаю, что это связано с StemmingAnalyzer, который Haystack использует в моем CharField. Я подробно рассмотрю это после.

ответ

1

Вы можете использовать QueryParser непосредственно увидеть, как Свист является разбор этого запроса:

>>> 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. Постройте запрос самостоятельно вместо кругооборот через нечетко определены и человеко-ориентированный язык запросов Свист в. Конечно, это работает только в том случае, если ваш индекс находится на одной машине, и вы читаете его с тем же процессом; Я ничего не знаю о Haystack.

  2. Не используйте косые черты в поле numero. Измените их на что-то менее похожее на синтаксис запроса, например на символы подчеркивания.

  3. Избегайте включения косой черты, когда вы делаете префиксный поиск; например, 6210202443* отлично работает в любом месте запроса.

+0

Я не думал об использовании QueryParser, спасибо :) – msbrogli

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. Не так ли?

Я хочу внести свой вклад с патчем, но я не уверен, действительно ли это ошибка в парсере. Зависит от приоритета, который имеет больше смысла.

+0

Это действительно должно быть редактирование вопроса :), но я внесло некоторые исправления в whoosh, и по моему опыту сопровождающий очень отзывчив; я либо [установил билет] (https://bitbucket.org/mchaput/whoosh/issues?status=new&status=open), либо просто оптимистично написал патч и отправил его как запрос на перенос. – Eevee