2014-03-29 3 views
1

저는 PostgreSQL을 처음 접했고 전체 텍스트 검색을 구현하는 데 몇 가지 문제가 있습니다.PostgreSQL에서 전체 텍스트 검색 쿼리를 설정하는 방법

WITH 
    q AS (SELECT plainto_tsquery('german', 'elephants php') AS query), 
    d AS (SELECT (name || ' ' || description) AS document FROM data_table), 
    t AS (SELECT to_tsvector('german', d.document) AS textsearch FROM d), 
    r AS (SELECT ts_rank_cd(t.textsearch, q.query) AS rank FROM t, q) 
SELECT data_table.*, ts_headline('german', d.document, q.query) AS matches 
FROM data_table, q, d, t , r 
WHERE q.query @@ t.textsearch 
ORDER BY r.rank DESC 
LIMIT 10; 
:

CREATE DATABASE test; 

CREATE TABLE data_table (
    id BIGSERIAL PRIMARY KEY, 
    name VARCHAR(160) NOT NULL, 
    description VARCHAR NOT NULL 
); 

CREATE INDEX data_table_idx ON data_table 
USING gin(to_tsvector('german', name || ' ' || description)); 

INSERT INTO data_table (name, description) VALUES 
    ('Penguin', 'This is the Linux penguin.'), 
    ('Gnu', 'This is the GNU gnu.'), 
    ('Elephant', 'This is the PHP elephant.'), 
    ('Elephant', 'This is the postgres elephant.'), 
    ('Duck', 'This is the duckduckgo duck.'), 
    ('Cat', 'This is the GitHub cat.'), 
    ('Bird', 'This is the Twitter bird.'), 
    ('Lion', 'This is the Leo lion.'); 

가 지금은 다음과 같이 어떻게 든 찾아야한다 하이라이트 경기 개미 전체 데이터 행을 특정 사용자 입력 테이블을 검색하고 반환하려고 : 저는 현재 다음과 같은 설정을 사용하고 있습니다 다음과 같은 출력으로 나를 잎

:

id | name |   description   |    matches    
----+----------+--------------------------------+------------------------------------ 
    5 | duck  | This is the duckduckgo duck. | Penguin This is the Linux penguin. 
    2 | Gnu  | This is the GNU gnu.   | Gnu This is the GNU gnu. 
    3 | Elephant | This is the PHP elephant.  | Penguin This is the Linux penguin. 
    4 | elephant | This is the postgres elephant. | Penguin This is the Linux penguin. 
    6 | Cat  | This is the GitHub cat.  | Penguin This is the Linux penguin. 
    1 | Penguin | This is the Linux penguin.  | Gnu This is the GNU gnu. 
    1 | Penguin | This is the Linux penguin.  | Penguin This is the Linux penguin. 
    2 | Gnu  | This is the GNU gnu.   | Penguin This is the Linux penguin. 
    4 | elephant | This is the postgres elephant. | Gnu This is the GNU gnu. 
    3 | Elephant | This is the PHP elephant.  | Gnu This is the GNU gnu. 
(10 rows) 

그래서 쿼리는 뭔가를 반환하지 있지만, 계급으로 분류되지 않은 각 문서가 각각 C와 결합 이름/설명의 비교 및 ​​작동하는 유일한 것은 문서의 검색 결과를 올바르게 강조한 것입니다. 그래서 내가 뭘 잘못하고 어떻게 고칠 수 있습니까?

+0

샘플 데이터/sqlfiddle? –

+0

@Craig 내 예제를 완성 했으므로 복사하여 내 쿼리를 복사하여 재현 할 수 있습니다. – Phidelux

답변

1

마지막으로 나는이 작업을 할 수있었습니다. 내 솔루션을 아래에서 찾으십시오. 나는 이것이 누군가를 돕기를 바랍니다. 누군가가 더 나은/더 빠른 인덱싱을 통해 더 나은 솔루션을 알고 있다면 기꺼이 알게 될 것입니다.

검색어 :

WITH 
    q AS (SELECT to_tsquery('german', 'elephant | php') AS query), 
    d AS (SELECT id, (name || ' ' || description) AS doc FROM data_table), 
    t AS (SELECT id, doc, to_tsvector('german', doc) AS vector FROM d), 
    r AS ( 
     SELECT id, doc, ts_rank_cd(vector, query) AS rank 
     FROM t, q 
     WHERE q.query @@ vector 
     ORDER BY rank DESC 
    ) 
SELECT id, ts_headline('german', doc, q.query) AS matches, rank 
FROM r, q 
ORDER BY r; 

결과 :

id |       matches       | rank 
----+---------------------------------------------------------+------ 
    3 | <b>Elephant</b> This is the <b>PHP</b> <b>elephant</b>. | 0.3 
    4 | <b>elephant</b> This is the postgres <b>elephant</b>. | 0.2