姓氏的相似性搜索



我有一列name其中包含name surname(命名空间姓氏(,我想根据

  • namesurname但我想匹配人们不小心以不同顺序插入surname name的情况
  • names surnames拼写错误 1-2 个字符。

您应该阅读有关pg_trgm扩展及其函数similarity()的信息。下面是几个例子。

示例数据:

create table my_table(id serial primary key, name text);
insert into my_table (name) values
('John Wilcock'),
('Henry Brown'),
('Jerry Newcombe');
create extension if not exists pg_trgm; -- install the extension

示例 1:

select *, 
    similarity(name, 'john wilcock') as "john wilcock",
    similarity(name, 'wilcock john') as "wilcock john"
from my_table;
 id |      name      | john wilcock | wilcock john 
----+----------------+--------------+--------------
  1 | John Wilcock   |            1 |            1
  2 | Henry Brown    |            0 |            0
  3 | Jerry Newcombe |     0.037037 |     0.037037
(3 rows)

示例 2:

select *, 
    similarity(name, 'henry brwn') as "henry brwn",
    similarity(name, 'brovn henry') as "brovn henry"
from my_table;
 id |      name      | henry brwn | brovn henry 
----+----------------+------------+-------------
  1 | John Wilcock   |          0 |           0
  2 | Henry Brown    |   0.642857 |         0.6
  3 | Jerry Newcombe |       0.04 |   0.0384615
(3 rows)

例3:

select *
from my_table
where similarity(name, 'J Newcombe') >= 0.6;
 id |      name      
----+----------------
  3 | Jerry Newcombe
(1 row) 

为了对抗名称的交换部分,您可以使用split_part()将名称分成两部分并比较它们,类似于以下内容:

SELECT *
       FROM person
       WHERE split_part(name, ' ', 1) IN ('<given_name_searched_for>'
                                          '<surname_searched_for>')
              OR split_part(name, ' ', 2) IN ('<given_name_searched_for>'
                                              '<surname_searched_for>');

或者看看其他字符串函数和运算符。 -- 有使用正则表达式的拆分函数的变体,例如

有没有像"约翰·肯尼迪"这样的名字,也就是说,有多个令牌?是否有具有多个连续空格的名称?请记住,如果有的话,必须通过进一步的手段解决这些问题。(这样的事情可能会变得毛茸茸的。如果可能,请考虑修改您的设计,并为姓氏使用单独的列。

对于相似性部分:PostgreSQL提供了一些模块,这些模块在这里可能很有用:

  • 模糊斯特拉匹配
  • pg_trm

最新更新