2016-09-26 180 views
0

如何确保我的全文搜索结果按精确匹配排序,然后是前缀匹配项?通过完全匹配命令全文搜索然后前缀匹配

SELECT ticker, name, ts_rank(document, to_tsquery('english', 'MAT:*')) AS rank 
FROM (
    SELECT *, setweight(to_tsvector('english', ticker), 'A') || setweight(to_tsvector('english', name), 'B') AS document 
    FROM (VALUES 
    ('MATI-R' , 'MATICHON PCL.NVDR') 
    ,('MATCH-R', 'MATCHING MAXIMIZE SLN. NVDR') 
    ,('MATV' , 'MATAV-CABLE SYS.MEDIA SPN.ADR 1:2 DEAD - DELIST.03/07/06') 
    ,('MAT' , 'MATISSE HOLDINGS DEAD - 03/10/06') 
    ,('MAT' , 'MATTEL') 
) data (ticker,name) 
) ss ORDER BY rank DESC 

我尝试了一些的建议上https://www.postgresql.org/docs/9.5/static/datatype-textsearch.htmlto_tsquery('english', 'MAT:A & MAT:*B')但没有似乎给了我,我要找的排序。电流输出是

ticker |       name       | rank 
---------+----------------------------------------------------------+---------- 
MATI-R | MATICHON PCL.NVDR          | 1.45903 
MATCH-R | MATCHING MAXIMIZE SLN. NVDR        | 1.27665 
MATV | MATAV-CABLE SYS.MEDIA SPN.ADR 1:2 DEAD - DELIST.03/07/06 | 1.09427 
MAT  | MATISSE HOLDINGS DEAD - 03/10/06       | 0.851098 
MAT  | MATTEL             | 0.851098 

时,我想更多的东西一样

ticker |       name       | rank 
---------+----------------------------------------------------------+---------- 
MAT  | MATTEL             | ?? 
MAT  | MATISSE HOLDINGS DEAD - 03/10/06       | ?? 
MATCH-R | MATCHING MAXIMIZE SLN. NVDR        | ?? 
MATI-R | MATICHON PCL.NVDR          | ?? 
MATV | MATAV-CABLE SYS.MEDIA SPN.ADR 1:2 DEAD - DELIST.03/07/06 | ?? 

回答

2

使用LIKEILIKE

SELECT ticker, name, ts_rank(document, to_tsquery('english', 'MAT:*')) AS rank 
FROM (
    SELECT *, setweight(to_tsvector('english', ticker), 'A') || setweight(to_tsvector('english', name), 'B') AS document 
    FROM (VALUES 
    ('MATI-R' , 'MATICHON PCL.NVDR') 
    ,('MATCH-R', 'MATCHING MAXIMIZE SLN. NVDR') 
    ,('MATV' , 'MATAV-CABLE SYS.MEDIA SPN.ADR 1:2 DEAD - DELIST.03/07/06') 
    ,('MAT' , 'MATISSE HOLDINGS DEAD - 03/10/06') 
    ,('MAT' , 'MATTEL') 
) data (ticker,name) 
) ss ORDER BY name LIKE concat('%', ticker, '%') desc, rank DESC 

ticker |       name       | rank 
---------+----------------------------------------------------------+---------- 
MAT  | MATISSE HOLDINGS DEAD - 03/10/06       | 0.851098 
MAT  | MATTEL             | 0.851098 
MATI-R | MATICHON PCL.NVDR          | 1.45903 
MATCH-R | MATCHING MAXIMIZE SLN. NVDR        | 1.27665 
MATV | MATAV-CABLE SYS.MEDIA SPN.ADR 1:2 DEAD - DELIST.03/07/06 | 1.09427 
(5 rows)  
+0

这很有趣。似乎它工作,如果我们排序'ticker'而不是'name',但它也似乎有点hacky,因为它跳过postgresql的全文搜索的排名能力。看起来使用全文搜索排名在更大的数据集上会更有效。任何原因你会建议使用全文搜索机器的方法? – Justin

+0

首先,您只能在全文搜索中找不到像这样的精确匹配。使用“like”不是全文搜索,而是旁边的。两个功能都很好地结合在一当然,对于大型数据集,'like'将会更加昂贵,但我不能看到替代方案来实现您想要的。 – klin

+0

有道理。我们现在正在使用一些标准化权重并看到相当不错的结果,但我认为我们最终将结合您的解决方案和这些结果。 – Justin