2015-01-08 3 views
2

Я пытаюсь реализовать pg_search в моем приложении Rails и задаюсь вопросом, есть ли способ получить столбец, соответствующий поисковому запросу? Содержимое таблицы индексов состоит из всех полей столбцов поиска.Как получить столбец, соответствующий поисковому запросу?

т.д .:

+-----------+----------+ 
| Firstname | Lastname | 
+-----------+----------+ 
| John  | Doe  | 
| Jane  | Doe  | 
+-----------+----------+ 

приведет:

+----------+ 
| Content | 
+----------+ 
| John Doe | 
| Jane Doe | 
+----------+ 

И теперь я не знаю, если мой поисковый запрос соответствует ПгвЬЫате или LastName. Есть ли какие-либо опции, чтобы сообщить pg_search, чтобы добавить заголовок столбца в колонку содержимого? Что-то вроде:

+------------------------------------------+ 
|     Content     | 
+------------------------------------------+ 
| {"firstname": "John", "Lastname": "Doe"} | 
| {"firstname": "Jane", "Lastname": "Doe"} | 
+------------------------------------------+ 

Или есть альтернативы поиска, которые соответствуют моим потребностям? pg_search работает очень хорошо, особенно из-за моей архитектуры multi-tenant/postgres-schema.

ответ

0

Раствор гнезда, вероятно, генерировать tsvectors + запрос на лету для каждого столбца соответствующих строк ..

Пример:

select *, 
(to_tsvector(p.first_name)@@ to_tsquery('joe:*')) found_in_first_name, 
(to_tsvector(p.last_name)@@ to_tsquery('joe:*')) found_in_last_name 
from people p 
where p.fts @@ to_tsquery('joe:*'); 

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

альтернативы взломать «вес», чтобы получить то, что вы желаете:

UPDATE people SET fts = 
    setweight(to_tsvector(coalesce(firstname,'')), 'A') || 
    setweight(to_tsvector(coalesce(lastname,'')), 'B'); 

Итак, что мы только что сделали, это дать первому столбцу «вес» столбца «A» и «lastname» «вес» «B» в tsvector. Имейте в виду, что «A», «B», «C» и «D» являются единственными допустимыми весами, поэтому, если вам нужно сделать это с более чем четырьмя столбцами, это не сработает.

Ваших запросы могут запросить определенный вес, если это необходимы, и вес, виден в текстовом представлении поискового вектора, однако они не доступны при поиске (IE, возвращая вес которых условие поиска было найдено в)

+0

Благодаря! Но я не понимаю, где разместить код 'tsvector' - ОК, я сам не понимаю сам код, я должен посмотреть на документацию, но: это даже работает с несколькими поисками? Если есть 40 результатов, нужно ли выполнять запрос выбора для каждой строки, даже если модели одинаковы? Разве это не будет убийцей производительности? Альтернатива 2 не будет работать для меня, так как я использую более 4 столбцов. Я думаю, что лучшим вариантом будет хранение JSON в таблице контента (и поскольку Postgres 9.4 это можно сделать с помощью JSONB). – Slevin

+0

Что значит «множественный поиск»? Мой первый пример работает с несколькими терминами, если это то, о чем вы просите. Что касается ваших моделей, этот код должен быть включен в ваши модели при запуске поиска, это дополнение к базовому оператору select, который уже выполняется, и это а не отдельный оператор выбора. –

Смежные вопросы