2012-10-17 25 views
10

Theo sau từ this answer Tôi muốn biết cách tốt nhất để sử dụng tìm kiếm văn bản đầy đủ của PostgreSQL là gì nếu tôi muốn sắp xếp theo thứ hạng, giới hạn .Cách tốt nhất để sử dụng xếp hạng tìm kiếm văn bản đầy đủ của PostgreSQL

Giả sử một bảng rất đơn giản.

CREATE TABLE pictures { 
    id SERIAL PRIMARY KEY, 
    title varchar(300), 
    ... 
} 

hoặc bất kỳ thứ gì. Bây giờ tôi muốn tìm kiếm trường title. Trước tiên, tôi tạo chỉ mục:

CREATE INDEX pictures_title ON pictures USING gin(to_tsvector('english', title)); 

Bây giờ tôi muốn tìm kiếm 'small dog'. Đây hoạt động:

SELECT pictures.id, ts_rank_cd(to_tsvector('english', pictures.title), 'small dog') AS score 
FROM pictures 
ORDER BY score DESC 

Nhưng những gì tôi thực sự muốn là thế này:

SELECT pictures.id, ts_rank_cd(to_tsvector('english', pictures.title), to_tsquery('small dog')) AS score 
FROM pictures WHERE to_tsvector('english', pictures.title) @@ to_tsquery('small dog') 
ORDER BY score DESC 

Hoặc cách khác này (mà không hoạt động - không thể sử dụng score trong mệnh đề WHERE):

SELECT pictures.id, ts_rank_cd(to_tsvector('english', pictures.title), to_tsquery('small dog')) AS score 
FROM pictures WHERE score > 0 
ORDER BY score DESC 

Cách tốt nhất để làm điều này là gì? Câu hỏi của tôi nhiều lần:

  1. Nếu tôi sử dụng phiên bản lặp đi lặp lại to_tsvector(...), nó có đủ để lưu kết quả bằng cách nào đó không?
  2. Có cách nào để thực hiện việc này mà không cần lặp lại các cuộc gọi chức năng to_ts... không?
  3. Có cách nào để sử dụng score trong mệnh đề WHERE không?
  4. Nếu có, sẽ tốt hơn nếu lọc theo score > 0 hoặc sử dụng điều @@?

Trả lời

10
select * 
from (
    SELECT 
     pictures.id, 
     ts_rank_cd(to_tsvector('english', pictures.title), 
     to_tsquery('small dog')) AS score 
    FROM pictures 
) s 
WHERE score > 0 
ORDER BY score DESC 
5

Nếu tôi sử dụng phiên bản với to_tsvector lặp đi lặp lại (...) sẽ nó gọi đó là hai lần, hoặc là nó đủ thông minh để cache kết quả bằng cách nào đó?

Cách tốt nhất để nhận thấy những điều này là thực hiện một giải thích đơn giản, mặc dù chúng có thể khó đọc.

Câu chuyện dài ngắn gọn, vâng, PostgreSQL đủ thông minh để sử dụng lại kết quả tính toán.

Có cách nào để thực hiện điều đó mà không cần lặp lại các cuộc gọi chức năng to_ts ... không?

Điều tôi thường làm là thêm một cột tsv là vectơ tìm kiếm văn bản. Nếu bạn thực hiện cập nhật tự động này bằng trình kích hoạt, ngay lập tức nó sẽ cho bạn véc tơ dễ truy cập nhưng nó cũng cho phép bạn cập nhật có chọn lọc chỉ mục tìm kiếm bằng cách kích hoạt chọn lọc.

Có cách nào để sử dụng điểm số trong mệnh đề WHERE không?

Có, nhưng không phải với tên đó. Hoặc bạn có thể tạo một truy vấn con, nhưng cá nhân tôi sẽ lặp lại nó.

Nếu có, sẽ tốt hơn nếu lọc theo điểm> 0 hoặc sử dụng @@ thing?

Phiên bản đơn giản nhất tôi có thể nghĩ là thế này:

SELECT * 
FROM pictures 
WHERE 'small dog' @@ text_search_vector 

Các text_search_vector rõ ràng có thể được thay thế bằng một cái gì đó giống như to_tsvector('english', pictures.title)

+0

Câu trả lời này bỏ qua những gì seemse là phần quan trọng nhất của câu hỏi: "xếp hạng" – steviejay