2012-10-25 14 views
15

Tôi đang cố chạy truy vấn fulltext bằng Postgresql có thể phục vụ cho các kết quả khớp một phần bằng cách sử dụng ký tự đại diện.Ký tự đại diện tiền tố Postgresql cho toàn văn

Có vẻ như đủ dễ dàng để có một ký tự đại diện bưu chính sau cụm từ tìm kiếm, tuy nhiên tôi không thể tìm ra cách chỉ định ký tự đại diện tiền tố.

Ví dụ, tôi có thể thực hiện tìm kiếm postfix dễ dàng đủ sử dụng một cái gì đó giống như ..

SELECT "t1".* 
FROM "t1" 
WHERE (to_tsvector('simple', "t1"."city") @@ to_tsquery('simple', 'don:*')) 

nên trả lại kết quả phù hợp với "London"

Tuy nhiên tôi không thể dường như thực hiện tìm kiếm tiền tố như .. .

SELECT "t1".* 
FROM "t1" 
WHERE (to_tsvector('simple', "t1"."city") @@ to_tsquery('simple', ':*don')) 

Lý tưởng nhất là tôi muốn có một wildcard tiền tố vào phía trước và kết thúc của cụm từ tìm kiếm một cái gì đó giống như ...

SELECT "t1".* 
FROM "t1" 
WHERE (to_tsvector('simple', "t1"."city") @@ to_tsquery('simple', ':*don:*')) 

Tôi có thể sử dụng điều kiện LIKE tuy nhiên tôi đã hy vọng được hưởng lợi từ hiệu suất của các tính năng tìm kiếm toàn văn trong Postgres.

+2

Theo hướng dẫn: http://www.postgresql.org/docs/current/static/textsearch-controls.html 'don: * ' ** là ** tìm kiếm * tiền tố *. Có thể bạn đang trộn tiền tố và tìm kiếm postfix? –

Trả lời

9

Tìm kiếm văn bản đầy đủ tốt cho việc tìm kiếm từ, không phải từ khóa.

Đối với tìm kiếm chuỗi con, bạn nên sử dụng like '%don%' với tiện ích pg_trgm sẵn có từ PostgreSQL 9.1 và using gin (column_name gin_trgm_ops) hoặc using gist (column_name gist_trgm_ops) chỉ mục. Nhưng chỉ số của bạn sẽ rất lớn (thậm chí nhiều lần lớn hơn bảng của bạn) và viết hiệu suất không tốt lắm.

Có một số very good example of using pg_trgm for substring search trên select * from depesz blog.

+0

Cảm ơn câu trả lời, chúng tôi đã thực hiện một cái gì đó tương tự đã có trong các truy vấn như vậy với việc bổ sung các trigram hy vọng điều này sẽ cho chúng ta đạt được hiệu suất chúng tôi yêu cầu. Cảm ơn một lần nữa. –

+0

cách sử dụng gist (column_name gist_trgm_ops) trên 2 cột thay vì một cột? –

6

Một cách hoang dã và điên rồ để làm việc đó là tạo chỉ mục tsvector của tất cả tài liệu, được đảo ngược. Và đảo ngược các truy vấn của bạn để tìm kiếm postfix.

Đây là cơ bản những gì Solr làm với nó ReversedWildcardFilterFactory

select 
reverse('brown fox')::tsvector @@ (reverse('rown') || ':*')::tsquery --true 
+2

Thực tế hay không, đó là một thủ thuật độc ác. – Medorator

+1

Thật không may nếu bạn sẽ truy vấn 'row' thay vì' rown', nó sẽ không trả lại kết quả. Lý do là nó sẽ kiểm tra từ đầu để bắt đầu, nhưng một lần nữa chỉ từ đầu tiên (cuối cùng trong tình huống này) thư, và không bao giờ từ giữa. –

+0

@BernardPotocki không có trong thông số kỹ thuật;) Tìm kiếm toàn văn bản đủ cứng mà không cần đế. Nếu bạn muốn tìm kiếm 'hàng' và khớp với' brown' thì đây là trường hợp sử dụng tốt cho regexp –