Текстовый поиск по триграмме postgresql с порядком результатов pg_search

Я реализовал поиск по триграмме с помощью гема pg_search на рельсах. https://github.com/Casecommons/pg_search

Проблема в том, что иногда порядок возвращаемых результатов кажется неправильным в соответствии с определением поиска по триграмме, которое показывает документация по драгоценному камню:

Поиск по триграмме работает, подсчитывая, сколько трехбуквенных подстрок (или «триграмм») совпадают между запросом и текстом.

Мое приложение получает строковый ввод от пользователя («111 Streetname») и возвращает список адресов, который соответствует значению Address.full_string при приблизительном поиске по триграмме.

Список примеров поиска

Поиск по триграмме: "1493 cambrid"

  • Results:
    • 100 Cambridgeside Pl
    • 100 Cambridgeside Pl
    • 150 Cambridgepark Dr
    • 1575 Cambridge St
    • 1573 Cambridge St
    • 1493 Cambridge St

Поиск по триграмме: "1493 cambr"

  • Result:
    • 1493 Cambridge St

Поиск по триграмме: "1493 cambri"

  • Results:
    • 1575 Cambridge St
    • 1573 Cambridge St
    • 1493 Cambridge St

Поиск по триграмме: "1493 cambridge"

  • Results:
    • 1493 Cambridge St
    • 5 Cambridgepark Dr
    • 7 Cambridgepark Dr
    • 100 Cambridgeside Pl
    • и многое другое

Вопрос

¿Почему «1493 Кембридж-стрит» не всегда на высоте? ¿Нужно ли мне изменять запрос поиска по триграмме или это просто так работает алгоритм?

Пример запроса

SELECT "addresses".*, (ts_rank((to_tsvector('simple', coalesce("addresses"."full_string"::text, ''))), (to_tsquery('simple', ''' ' || '1493' || ' ''') && to_tsquery('simple', ''' ' || 'cambridge' || ' ''')), 0)) AS pg_search_rank FROM "addresses" WHERE (((coalesce("addresses"."full_string"::text, '')) % '1493 cambridge')) ORDER BY pg_search_rank DESC, "addresses"."id" ASC

person Mono    schedule 18.01.2013    source источник


Ответы (1)


Пока вы цитируете руководство по поиску по триграмме , вы фактически работаете с функцией ts_rank() из текстового поиска .

Если вы заказываете результаты по

(addresses.full_string <-> '1493 cambridge')

... вы получаете то, о чем просите.
<-> - оператор триграммы "расстояние".

Вы также можете использовать оператор % («подобие») в предложении WHERE. В идеале для этого у вас должен быть индекс GiST с gist_trgm_ops в столбце.

person Erwin Brandstetter    schedule 18.01.2013