PostgreSQL中的短语比较
如何在Postgres表中的varchar列中查找包含相同3个单词短语的行 其他问题中的大部分全文搜索建议都是将向量与特定查询进行比较,但我要查找的是与其他行一样包含任何3个单词短语的行 例如:PostgreSQL中的短语比较,postgresql,Postgresql,如何在Postgres表中的varchar列中查找包含相同3个单词短语的行 其他问题中的大部分全文搜索建议都是将向量与特定查询进行比较,但我要查找的是与其他行一样包含任何3个单词短语的行 例如: SELECT * FROM types t1 WHERE EXISTS (SELECT * FROM types t2 WHERE t1.name phrase_matches t2.name AND t1
SELECT *
FROM types t1
WHERE EXISTS (SELECT *
FROM types t2
WHERE t1.name phrase_matches t2.name
AND t1.id > t2.id)
这里,phrase\u matches
是一个虚构的操作,其中
'my foo bar baz'短语与'foo bar baz whatever'匹配
返回true
及
'my foo-bar-baz'短语与'foo-baz which bar'匹配
返回false
编辑:为来自谷歌的任何人更新-没有临时表的解决方案,使用连接,在一个有18k行的表上花费了一个多小时。临时表版本总共在几秒钟内运行。创建一个包含行ID的三角形表,然后在三角形列上进行自联接。浪费大量的空间,但这是最简单的方法。在以下方面的帮助下:
为行ID创建一个三角形表,然后在三角形列上进行自联接。浪费大量的空间,但这是最简单的方法。在以下方面的帮助下:
可能有更好的选择,但你也可以这样做。这不完全是你所要求的,但我相信你能用这个想法来推动它
select n.name from(
select x.name as xname,count(*) from
(
(
select name,unnest(string_to_array(name2,' ')) as name2
from new
)as x
inner join
(
select name,unnest(string_to_array(name,' ')) as name1
from new
)as y
on x.name2=y.name1 and y.id>x.id
) group by x.name having count(*)>=3)r inner join new n on r.xname=n.name
这里有一把同样的小提琴:
注意我的小提琴中没有id,但你可以自己做。可能有更好的选择,但你也可以这样做。这不完全是你所要求的,但我相信你能用这个想法来推动它
select n.name from(
select x.name as xname,count(*) from
(
(
select name,unnest(string_to_array(name2,' ')) as name2
from new
)as x
inner join
(
select name,unnest(string_to_array(name,' ')) as name1
from new
)as y
on x.name2=y.name1 and y.id>x.id
) group by x.name having count(*)>=3)r inner join new n on r.xname=n.name
这里有一把同样的小提琴:
注意我的小提琴中没有id,但你可以自己做。
结果:
phrase
my foo bar baz
foo baz whatever bar
foo bar baz whatever
blah my foo bar blah
blah my foo baz blah
a b check_phrase
blah my foo bar blah my foo bar baz my foo bar
foo bar baz whatever my foo bar baz foo bar baz
my foo bar baz foo bar baz whatever foo bar baz
blah my foo baz blah blah my foo bar blah blah my foo
my foo bar baz blah my foo bar blah my foo bar
blah my foo bar blah blah my foo baz blah blah my foo
words
创建所有短语的所有单词列表。所有单词都会得到一个索引,以确保它们在短语中的原始顺序phrase\u parts
创建所有可能的3个单词短语:对于每个原始短语,所有单词都连接在一起phrase unnest row_number phrase unnest row_number
my foo bar baz my 1 my foo bar baz my 1
my foo bar baz my 1 my foo bar baz foo 2
my foo bar baz my 1 my foo bar baz bar 3
my foo bar baz my 1 my foo bar baz baz 4
my foo bar baz foo 2 my foo bar baz foo 2
my foo bar baz foo 2 my foo bar baz bar 3
my foo bar baz foo 2 my foo bar baz baz 4
my foo bar baz bar 3 my foo bar baz bar 3
my foo bar baz bar 3 my foo bar baz baz 4
my foo bar baz baz 4 my foo bar baz baz 4
foo baz whatever bar foo 5 foo baz whatever bar foo 5
foo baz whatever bar foo 5 foo baz whatever bar baz 6
foo baz whatever bar foo 5 foo baz whatever bar whatever 7
foo baz whatever bar foo 5 foo baz whatever bar bar 8
foo baz whatever bar baz 6 foo baz whatever bar baz 6
...
使用,我可以通过以下方式聚合第二个unnest
列:
array_agg
{my}
{my,foo}
{my,foo,bar}
{my,foo,bar,baz}
{foo}
{foo,bar}
{foo,bar,baz}
{bar}
{bar,baz}
{baz}
{foo}
{foo,baz}
{foo,baz,whatever}
{foo,baz,whatever,bar}
...
这将被过滤为数组长度=3
,并重新转换为字符串。结果是3个单词短语:
phrase
my foo bar baz
foo baz whatever bar
foo bar baz whatever
blah my foo bar blah
blah my foo baz blah
a b check_phrase
blah my foo bar blah my foo bar baz my foo bar
foo bar baz whatever my foo bar baz foo bar baz
my foo bar baz foo bar baz whatever foo bar baz
blah my foo baz blah blah my foo bar blah blah my foo
my foo bar baz blah my foo bar blah my foo bar
blah my foo bar blah blah my foo baz blah blah my foo
words
创建所有短语的所有单词列表。所有单词都会得到一个索引,以确保它们在短语中的原始顺序phrase\u parts
创建所有可能的3个单词短语:对于每个原始短语,所有单词都连接在一起phrase unnest row_number phrase unnest row_number
my foo bar baz my 1 my foo bar baz my 1
my foo bar baz my 1 my foo bar baz foo 2
my foo bar baz my 1 my foo bar baz bar 3
my foo bar baz my 1 my foo bar baz baz 4
my foo bar baz foo 2 my foo bar baz foo 2
my foo bar baz foo 2 my foo bar baz bar 3
my foo bar baz foo 2 my foo bar baz baz 4
my foo bar baz bar 3 my foo bar baz bar 3
my foo bar baz bar 3 my foo bar baz baz 4
my foo bar baz baz 4 my foo bar baz baz 4
foo baz whatever bar foo 5 foo baz whatever bar foo 5
foo baz whatever bar foo 5 foo baz whatever bar baz 6
foo baz whatever bar foo 5 foo baz whatever bar whatever 7
foo baz whatever bar foo 5 foo baz whatever bar bar 8
foo baz whatever bar baz 6 foo baz whatever bar baz 6
...
使用,我可以通过以下方式聚合第二个unnest
列:
array_agg
{my}
{my,foo}
{my,foo,bar}
{my,foo,bar,baz}
{foo}
{foo,bar}
{foo,bar,baz}
{bar}
{bar,baz}
{baz}
{foo}
{foo,baz}
{foo,baz,whatever}
{foo,baz,whatever,bar}
...
这将被过滤为数组长度=3
,并重新转换为字符串。结果是3个单词短语:
但是我有一个无限(理论上)的短语集。这个答案并不预设任何特定数量的短语——它只会找到有共享短语的行——只要子短语长度设置好。我把你在问题中提到的三个放进去;这并不意味着你不能拥有更多。因此,我首先必须浏览表格,并用数据中可能出现的所有短语填充短语表格,对吗?我展示了两种方式-快速但占用大量空间,或者缓慢但不占用额外空间。你必须牺牲一个,你的选择。呃,不,我误解了,你也是<代码>短语是您的表格。在我的代码中,它只是为了说明你在OP中显示的起始数据。那里没有提取过程——这正是你所说的数据。如果它的列名与您的表不完全相同,或者表名不完全相同,请相应地进行调整。它甚至在评论中说“你的数据:),但我有一个无限(理论上)的短语集。这个答案并不预设任何特定数量的短语——它只找到有共享短语的行——只要设置了子短语长度。我把你在问题中提到的三个放进去;这并不意味着你不能拥有更多。因此,我首先必须浏览表格,并用数据中可能出现的所有短语填充短语表格,对吗?我展示了两种方式-快速但占用大量空间,或者缓慢但不占用额外空间。你必须牺牲一个,你的选择。呃,不,我误解了,你也是<代码>短语是您的表格。在我的代码中,它只是为了说明你在OP中显示的起始数据。那里没有提取过程——这正是你所说的数据。如果它的列名与您的表不完全相同,或者表名不完全相同,请相应地进行调整。它甚至在评论中说“你的数据:)