postgresql - 同时使用 trigram 和 ILIKE

标签 postgresql trigram

我有 GIN 索引列,使用 gin_trgm_ops 进行索引。

我正在使用相似性搜索术语“mad”:

我得到:

god-made
made
man
man-made
may

但它遗漏了一些单词,例如srimad

我想选择 ILIKE '%mad%''mad%' 的前 5 个三元组,然后选择前 5 个三元组并合并结果。

实现解决方案后:

我的 SQL 查询和解释:

EXPLAIN (COSTS OFF)
(SELECT word_similarity('mad',word), word FROM articles_words WHERE word ILIKE '%mad%' ORDER BY word_similarity('mad',word) DESC LIMIT 10) 
UNION 
(SELECT word_similarity('mad',word),word FROM articles_words WHERE word_similarity('mad',word) > 0.4 ORDER BY word_similarity('mad',word) DESC, word LIMIT 10)

  "QUERY PLAN"
"HashAggregate"
"  Group Key: (word_similarity('mad'::text, articles_words.word)), articles_words.word"
"  ->  Append"
"        ->  Limit"
"              ->  Sort"
"                    Sort Key: (word_similarity('mad'::text, articles_words.word)) DESC"
"                    ->  Bitmap Heap Scan on articles_words"
"                          Recheck Cond: (word ~~* '%mad%'::text)"
"                          ->  Bitmap Index Scan on words_idx"
"                                Index Cond: (word ~~* '%mad%'::text)"
"        ->  Limit"
"              ->  Sort"
"                    Sort Key: (word_similarity('mad'::text, articles_words_1.word)) DESC, articles_words_1.word"
"                    ->  Seq Scan on articles_words articles_words_1"
"                          Filter: (word_similarity('mad'::text, word) > '0.40000000000000002'::double precision)"

还有关于 UNION 的问题:

第一个查询项目:

(SELECT word_similarity('mad',word), word FROM articles_words WHERE word ILIKE '%mad%' ORDER BY word_similarity('mad',word) DESC LIMIT 10)

0.75 man-made
0.75 made
0.75 god-made
0.5 srimad-bhagavatam
0.5 srimad

第二个查询项:

(SELECT word_similarity('mad',word),word FROM articles_words WHERE word_similarity('mad',word) > 0.4 ORDER BY word_similarity('mad',word) DESC, word LIMIT 10)

0.75 god-made
0.75 made
0.75 man-made
0.5 anti-material
0.5 half-man
0.5 magistrate
0.5 maha
0.5 maha-mantra
0.5 mahaprabhu
0.5 maharaja

我想要结果为:

0.75 man-made
0.75 made
0.75 god-made
0.5 srimad-bhagavatam
0.5 srimad
0.5 anti-material
0.5 half-man
0.5 magistrate
0.5 maha
0.5 maha-mantra
0.5 mahaprabhu
0.5 maharaja

但我按照以下顺序:

0.75 god-made
0.5 maha
0.5 anti-material
0.5 mahaprabhu
0.5 maharaja
0.5 srimad
0.5 half-man
0.5 magistrate
0.5 srimad-bhagavatam
0.75 made
0.75 man-made
0.5 maha-mantra

最佳答案

您应该使用 GiST 索引。

如下表:

test=> TABLE trigram;
 id |   val    
----+----------
  1 | god-made
  2 | made
  3 | man
  5 | man-made
  4 | may
  6 | srimad
...

您可以像这样创建索引:

CREATE INDEX ON trigram USING gist (val gist_trgm_ops);

它可以在这样的查询中使用:

EXPLAIN (COSTS off)
(SELECT id, val
 FROM trigram
 WHERE val ILIKE '%mad%'
 LIMIT 5)
UNION
(SELECT id, val
 FROM trigram
 ORDER BY val <-> 'mad'
 LIMIT 5);
                                  QUERY PLAN                                   
-------------------------------------------------------------------------------
 HashAggregate
   Group Key: trigram.id, trigram.val
   ->  Append
         ->  Limit
               ->  Index Scan using trigram_val_idx on trigram
                     Index Cond: (val ~~* '%mad%'::text)
         ->  Subquery Scan on "*SELECT* 2"
               ->  Limit
                     ->  Index Scan using trigram_val_idx on trigram trigram_1
                           Order By: (val <-> 'mad'::text)
(10 rows)

关于postgresql - 同时使用 trigram 和 ILIKE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48928230/

相关文章:

string - 使用三元组相似度运算符进行多列相似度比较 %

sql - 如何在不列出列的情况下对每一列执行相同的聚合?

sql - 如何调整此查询以使用窗口函数

c# - 为 EntityFramework6.Npgsql 指定数据库连接字符串 - Code First

postgresql - 无法连接到 Tryton 数据库

google-bigquery - 如何在 Google BigQuery 中执行三元运算?

postgresql - 全文搜索中的模糊搜索

python - 使用多处理池更新 Django 模型会锁定数据库

nlp - 实现三元马尔可夫模型

用 C 计算三元组(3 个字母序列)?