我有一个捷克语单词(> 1M行)的PostgreSQL表,其中有一列名为“单词” [文本],我想根据单词结尾查找所有具有相同偏角的单词(请参阅Czech declination。
例如我想找到所有以“ e”结尾的单词(例如kuře),但是对于那些也存在以“ ete”(例如kuřete)和“ etem”(例如kuřetem)以及“ eti”(例如kuřeti)。对于每个单词,大约存在。 14个字词形式。
什么是找到所有与规则匹配的单词的有效方法(SQL查询)?
这是关系划分的情况。
假设有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发行版中未包含该词干。相关:
嗯。 。 。如果我理解正确,那么这不是高效的操作。但我认为,除非您采用神秘的索引策略(即使那样可能仍然行不通),否则聚合可能是最快的方法:select left(word, length(word) - 1) || 'e'
from words w
where word ~ '(e|ete|etem)$'
group by left(word, length(word) - 1);