GIN 인덱스 TSVECTOR 열에서 부분 일치를 가져옵니다.


13

이것을 쿼리하여 결과를 얻고 싶습니다.

SELECT * FROM (
  SELECT id, subject
  FROM mailboxes
  WHERE tsv @@ plainto_tsquery('avail')
) AS t1 ORDER by id DESC;

이것은 작동하고 tsv포함 하여 행을 반환합니다 Available. 그러나 avai( 사용 lable하지 않으면) 아무것도 찾을 수 없습니다.

모든 쿼리가 사전에 있어야합니까? 그런 편지 만 쿼리 할 수 ​​없습니까? 전자 메일 본문 (콘텐츠)이 포함 된 데이터베이스가 있으며 매 초마다 빠르게 증가하고 싶습니다. 현재 사용하고 있습니다

... WHERE content ~* 'letters`

답변:


22

모든 쿼리가 사전에 있어야합니까?

아닙니다. 사용 된 텍스트 검색 구성 에 따라 단어 스템 만 색인에 포함되기 때문입니다. 그러나 더 중요한 것은 :

없음 . 그 꼭대기에 있기 때문에 검색은 전체 텍스트할 수있는 접두사 일치 :

이것은 작동합니다 :

SELECT id, subject
FROM   mailboxes
WHERE  tsv @@ to_tsquery('simple', 'avail:*')
ORDER  BY id DESC;

3 가지 주의 사항 :

  1. 이 경우 to_tsquery(), not을 사용하십시오 plainto_tsquery()( 매뉴얼 인용 ).

    ... 입력에서 연산자, 가중치 레이블 또는 접두사 일치 레이블을 plainto_tsquery인식하지 못합니다.tsquery

  2. 'avail' 이라는 단어 를 그대로 사용하고 형태소 분석을 적용하지 않기 때문에 'simple'텍스트 검색 구성을 사용하여 를 생성하십시오 .tsquery

  3. :*접두사 검색을 만들기 위해 추가 하십시오. 즉 'avail'로 시작하는 모든 룩 셈스를 찾으십시오.

중요 사항 : 이것은 문서의 어휘 (단어)에 대한 접두사 검색입니다. 와일드 카드 ( content ~* 'avail')가없는 정규식 일치 는 정확히 동일하지 않습니다! 후자는 고정되어 있지 않으며 (lexemes가 시작될 때까지) 'FOOavail'등을 찾습니다.

쿼리에 동작의 개요를 추가할지 또는 추가 된 정규식에 해당하는지 명확하지 않습니다. @Evan pg_trgm과 같은 Trigram 인덱스 ( )는 이미 올바른 도구입니다. dba.SE에 관한 많은 관련 질문이 있습니다 . 검색을 시도하십시오 .

개요 :

데모

SELECT *
FROM (
   VALUES
     ('Zend has no framework')
   , ('Zend Framework')
   ) sub(t), to_tsvector(t) AS tsv
WHERE tsv @@ to_tsquery('zend <-> fram:*');
 id |       t        |          tsv
----+----------------+------------------------
  2 | Zend Framework | 'framework':2 'zend':1

최근 관련 답변 ( 검색 최적화를위한 다른 접근 방식 ) :

이메일?

이메일을 언급 했으므로 텍스트 검색 구문 분석기는 이메일을 식별하고 별도의 단어 / exe로 나누지 않습니다. 치다:

SELECT ts_debug('english', 'xangr@some.domain.com')
(email,"Email address",xangr@some.domain.com,{simple},simple,{xangr@some.domain.com})

포함 된 단어를 색인화 하기 위해 구분 기호 @.전자 메일의 공백을 공백 ( ' ')으로 바꿉니다.

또한 영어 (또는 다른 언어) 단어가 아닌 전자 메일의 이름 을 다루 므로 텍스트 검색 구성을 사용하여 형태소 분석 및 기타 언어 기능 을 비활성화 합니다.'simple'

다음을 사용하여 ts_vector열을 작성하십시오 .

SELECT to_tsvector('simple', translate('joe.xangr@some.domain.com', '@.', '  ')) AS tsv;

나는 처음으로 분명히 틀 렸기 때문에 어느 쪽이든 생각 나지 않기 때문에 이것에 대한 대답을 삭제하고 있습니다. 나는 당신에게 두 가지 질문이 있습니다 .1) 어디에 :*문서화되어 있으며 2) 빌드 할 언급 to_tsvector('simple'..)이 tsv의 미래 쿼리에 tsquery에도 '간단한'구성이 필요하다는 지시와 함께 제공해서는 안됩니까? tsvector / tsquery에서 형태소 분석을 비활성화 한 결과를 분명히해야한다고 생각합니다.
Evan Carroll

@EvanCarroll : '간단한'구성 사용이 필요 하지 않습니다 . 그것은 바람직하거나 바람직하지 않은 형태소 분석 ( '랫'에서 '랫'으로)을 피합니다. 주어진 예에는 바람직하지 않습니다. 수동 : 위의 링크를 추가했습니다 ...
Erwin Brandstetter

4
@EvanCarroll : 제쳐두고 : 당신이 처음 으로 틀렸다고 생각하면 두 번째입니다. 그리고 그것은 재귀 적으로 잘못 될 것입니다. ;)
Erwin Brandstetter 4

2
@ ErwinBrandstetter, 와우, 당신의 방법은 나에게 최고 속도 검색을 주었다. 당신의 길을 가기 전에 0.380ms결과를 얻었습니다. 당신의 방법 후에 그것은 걸렸다 0.079 ms.
xangr

1
@xangr : 아니요. FTS는 렉 세스에 대한 접두사 일치 만 제공 합니다 . 자세한 내용은을 참조하십시오 pg_trgm. FTS가 빠릅니다 (작은 인덱스 일수록). 두 인덱스를 결합 할 수도 있습니다 ...
Erwin Brandstetter
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.