2014-12-03 11 views
5

Tôi đang sử dụng bát quái để tìm kiếm toàn văn trong postgres như thế này:Làm thế nào để thực hiện bản đồ đơn giản giảm trong Postgres?

SELECT * 
FROM "Users" users 
WHERE 'search_text' % ANY(regexp_split_to_array(users.name,E'\\s+')) 

Query trên kiểm tra nếu search_text phù hợp với bất kỳ từ nào (chia bởi whitespace) trong User.displayName. Tuy nhiên, kết quả này không được sắp xếp theo "điểm số" thực tế.

Điểm có thể được tính bằng hàm similarity(text,text).

Vấn đề là tôi phải sắp xếp theo thứ tự tổng hợp tất cả các điểm giống nhau được tìm thấy cho mỗi từ trong User.name. Vì vậy, nếu tên người dùng là "A B C" sau đó điểm của nó nên là:

similarity('search_text','A') + similarity('search_text','B') + similarity('search_text','C') 

Vì vậy, tôi cần để ánh xạ từ tên người dùng để điểm số và sau đó sum (giảm) cho họ. Làm thế nào tôi có thể làm điều này trong postgres?

Trả lời

1

Trong thay vì chia nhỏ file thành một mảng tách một tập sau đó tập hợp lại cách tổng hợp các sự tương đồng

with users as (
    select user_id, name 
    from (values (1, 'John Smith')) t(user_id, name) 
) 
select user_id, sum(similarity('smth', name_part)) 
from (
    select user_id, regexp_split_to_table(name, E'\\s+') as name_part 
    from users 
) users 
where 'smth' % name_part 
group by user_id 
order by 2 desc 
; 
user_id | sum 
---------+------- 
     1 | 0.375 

Tôi không chắc chắn bạn muốn loại bỏ những phần tên mà sự tương đồng thấp hơn ngưỡng. Nếu không chỉ bỏ qua mệnh đề where

BTW, tại sao bạn cần phải tách tên? Tại sao không chỉ so sánh toàn bộ tên với chuỗi tìm kiếm?

with users as (
    select user_id, name 
    from (values (1, 'John Smith')) t(user_id, name) 
) 
select similarity('jon smth', name), * 
from users 
order by 1 desc 
; 
similarity | user_id | name  
------------+---------+------------ 
    0.333333 |  1 | John Smith 
Các vấn đề liên quan