有效的查询来查找与基于多行的规则匹配的行

问题描述 投票:0回答:2

我有一个捷克语单词(> 1M行)的PostgreSQL表,其中有一列名为“单词” [文本],我想根据单词结尾查找所有具有相同偏角的单词(请参阅Czech declination

例如我想找到所有以“ e”结尾的单词(例如kuře),但是对于那些也存在以“ ete”(例如kuřete)和“ etem”(例如kuřetem)以及“ eti”(例如kuřeti)。对于每个单词,大约存在。 14个字词形式。

什么是找到所有与规则匹配的单词的有效方法(SQL查询)?

sql postgresql nlp relational-division
2个回答
1
投票

这是关系划分的情况。

假设有UNIQUE个单词的表,例如:

CREATE TABLE words (word text PRIMARY KEY);

这应该是最快的解决方案之一:

SELECT w0.stem
FROM  (
   SELECT left(word, -4) AS stem  -- -4 = length('etem')
   FROM   words
   WHERE  word LIKE '%etem'  -- pick the most selective ending to get started
   ) w0
JOIN   words w1 ON w1.word = stem || 'eti'
JOIN   words w2 ON w2.word = stem || 'ete'
JOIN   words w3 ON w3.word = stem || 'e';

查找所有带有给定结尾的词干。具有相同词干和不同结尾的更多单词不会取消资格!

如果必须检查许多结尾(14?),则将其全部拼写可能很乏味。较短的代码,通常较慢:

SELECT w0.stem
FROM  (
   SELECT left(word, -4) AS stem
   FROM   words
   WHERE  word LIKE '%etem'  -- pick the most selective ending to get started
   ) w0
CROSS  JOIN unnest ('{eti,ete,e}'::text[]) x(dec)  -- all other in an array
JOIN   words w1 ON w1.word = w0.stem || x.dec
GROUP  BY w0.stem
HAVING count(*) = 3;  -- = cardinality('{eti,ete,e}'::text[])

db <>小提琴here

相关:

Text search个运算符和索引可能很感兴趣。但是,您首先需要捷克词干,但标准Postgres发行版中未包含该词干。相关:


0
投票

嗯。 。 。如果我理解正确,那么这不是高效的操作。但我认为,除非您采用神秘的索引策略(即使那样可能仍然行不通),否则聚合可能是最快的方法:select left(word, length(word) - 1) || 'e' from words w where word ~ '(e|ete|etem)$' group by left(word, length(word) - 1);

© www.soinside.com 2019 - 2024. All rights reserved.