标签: trigram

PostgreSQL,三元组和相似性

只是在我的Mac上测试PostgreSQL 9.6.2并使用Ngrams.假设酿酒厂有一个GIN三元组指数.

相似性的限制(我知道这已被弃用):

SELECT set_limit(0.5);
Run Code Online (Sandbox Code Playgroud)

我正在2,3M行表上构建一个trigram搜索.

我的选择代码:

SELECT winery, similarity(winery, 'chateau chevla blanc') AS similarity 
FROM usr_wines 
WHERE status=1 AND winery % 'chateau chevla blanc'  
ORDER BY similarity DESC;
Run Code Online (Sandbox Code Playgroud)

我的结果(在我的Mac上329毫秒):

Chateau ChevL Blanc 0,85
Chateau Blanc   0,736842
Chateau Blanc   0,736842
Chateau Blanc   0,736842
Chateau Blanc   0,736842
Chateau Blanc,  0,736842
Chateau Blanc   0,736842
Chateau Cheval Blanc    0,727273
Chateau Cheval Blanc    0,727273
Chateau Cheval Blanc    0,727273
Chateau Cheval Blanc (7)    0,666667
Chateau Cheval Blanc Cbo    0,64
Chateau Du Cheval Blanc 0,64
Chateau …
Run Code Online (Sandbox Code Playgroud)

postgresql similarity trigram

8
推荐指数
3
解决办法
2534
查看次数

Postgres word_similarity 不比较单词

"返回一个数字,表示第一个字符串与第二个字符串中最相似的单词的相似程度。该函数在第二个字符串中搜索最相似的单词而不是最相似的子字符串。结果的范围为零(表示两个字符串完全不同)到一个(表示第一个字符串与第二个字符串的一个单词相同)。”

这就是 word_similarity(a,b) 的定义,据我了解,它会在文本 b 中查找 WORD a,将 b 按单词拆分并获得最高匹配单词的分数。

但是,我看到了一些不一致的地方,单词匹配不是真的按单词匹配,看起来所有的三元组都被打乱并进行了比较?

例子:

select word_similarity('sage', 'message sag')
Run Code Online (Sandbox Code Playgroud)

返回 1,显然 'message' 或 'sag' 都不应该与 'sage' 匹配,但是如果我们组合来自 'message sag' 的可能的三元组,我们会发现来自 'sage' 的所有三元组都匹配,但事实并非如此真的应该发生什么,因为函数描述一个字一个字地谈论......是因为两个词彼此相邻吗?

以下将返回 0.6 分:

select word_similarity('sage', 'message test sag') 
Run Code Online (Sandbox Code Playgroud)

编辑:小提琴玩http://sqlfiddle.com/#!17/b4bab/1

postgresql words similarity trigram

8
推荐指数
1
解决办法
3200
查看次数

来自ManyToManyField的Django最大相似度(TrigramSimilarity)

我必须实现一个容错的搜索功能.
目前,我有以下情况:

楷模:

class Tag(models.Model):
    name = models.CharField(max_length=255)

class Illustration(models.Model):
    name = models.CharField(max_length=255)
    tags = models.ManyToManyField(Tag)
Run Code Online (Sandbox Code Playgroud)

查询:

queryset.annotate(similarity=TrigramSimilarity('name', fulltext) + TrigramSimilarity('tags__name', fulltext))
Run Code Online (Sandbox Code Playgroud)

示例数据:

插图:

ID |  Name  |        Tags       |
---|--------|-------------------|
 1 | "Dog"  | "Animal", "Brown" |
 2 | "Cat"  | "Animals"         |
Run Code Online (Sandbox Code Playgroud)

插图有标签:

ID_Illustration | ID_Tag |
----------------|--------|
       1        |    1   |
       1        |    2   |
       2        |    3   |
Run Code Online (Sandbox Code Playgroud)

标签:

ID_Tag |   Name   |
-------|----------|
   1   |  Animal  |
   2   |  Brown   |
   3   |  Animals | …
Run Code Online (Sandbox Code Playgroud)

python django postgresql django-queryset trigram

8
推荐指数
1
解决办法
1427
查看次数

ElasticSearch使用ngram术语的"最佳匹配"而不是"同义词"?

是否有可能告诉ElasticSearch使用所有克的"最佳匹配"而不是使用克作为同义词?

默认情况下,ElasticSearch使用gram作为同义词并返回不匹配的文档.最好以示例的方式展示,假设我们在索引中有两个人:

alice wang
sarah kerry
Run Code Online (Sandbox Code Playgroud)

我们搜索ali12345:

{
  query: {
    bool: {
      should: {
        match: { name: 'ali12345' }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

它会回来的alice wang.

这怎么可能?因为默认情况下ElasticSearch使用gram作为同义词,因此,即使只有一克匹配 - 文档也会匹配.

如果您检查查询,您会看到它将克视为同义词

...
"explanation": {
  "value": 5.274891,
  "description": "weight(Synonym(name: ali name:li1 name:i12 name:123 name:234 name:345 ) in 0) [PerFieldSimilarity], result of:",
...
Run Code Online (Sandbox Code Playgroud)

我想知道是否有可能告诉它使用"最佳匹配"查询,以达到如下目的:

{
  query: {
    bool: {
      should: [
        { term: { body: 'ali' }},
        { term: { body: 'li1' }},
        { term: { body: 'i12' …
Run Code Online (Sandbox Code Playgroud)

n-gram elasticsearch trigram

7
推荐指数
1
解决办法
518
查看次数

字符串匹配的多列索引+与pg_trgm的字符串相似性?

给这个表:

foos
integer id
string name
string type
Run Code Online (Sandbox Code Playgroud)

和这样的查询:

select * from foos where name ilike '%bar%'
Run Code Online (Sandbox Code Playgroud)

我可以像这样制作一个pg_trgm索引,以便更快地进行查找:

CREATE INDEX ON foos USING gin (name gin_trgm_ops)
Run Code Online (Sandbox Code Playgroud)

(对?)

我的问题:这样的查询怎么样:

select * from foos where name ilike '%bar%' AND type = 'baz'
Run Code Online (Sandbox Code Playgroud)

我可以创建一个有助于查找两列的索引吗?

(我知道trigram不是严格的全文,但我正在这样标记这个问题)

sql postgresql full-text-search trigram

6
推荐指数
1
解决办法
2248
查看次数

实现trigram markov模型

鉴于:

在此输入图像描述

以下内容:

在此输入图像描述

用于:

q(runs | the, dog) = 0.5
Run Code Online (Sandbox Code Playgroud)

这不应该1q(runs | the, dog):xi = run,xi-2 = the,xi-1 = dog

概率是(wi已被替换为xi):

在此输入图像描述

因此:

count(the dog runs) / count(the dog) = 1 / 1 = 1
Run Code Online (Sandbox Code Playgroud)

但在上面的例子中,该值为0.5.0.5如何到达?

基于http://files.asimihsan.com/courses/nlp-coursera-2013/notes/nlp.html#markov-processes-part-1

nlp markov trigram

6
推荐指数
1
解决办法
538
查看次数

通过最常用的词自动完成 - postgres 或 lucene?

我们正在使用 Postgres 及其全文功能在我们的系统中搜索文档(帖子内容),并且效果非常好。

对于自动完成,我们希望使用文档中使用的所有单词构建索引(字典?)并按最常用的单词进行搜索。我们将永远寻找一个词。我们永远不会搜索短语。

所以如果我写:

  • “那个”

我将收到(假设我们文档中最常用的词):

  • “这个”
  • “那里”
  • “想法”
  • ...

如何用 Postgres 做到这一点?或者我们可能需要一些更高级的解决方案,比如 apache lucene / solr ?

postgres 全文搜索(提供词素)和 postgres trigrams 似乎都不适合这项工作。或者也许我错了?

我不想手动解析文本并忽略所有容易出错的英语停用词。Postgres 在构建词法索引时在这方面做得很好。但是除了词素,我们需要建立和搜索没有规范化的词词典

谢谢您的帮助

lucene postgresql full-text-search autocomplete trigram

6
推荐指数
0
解决办法
283
查看次数

优化postgres相似性查询(pg_trgm + gin索引)

我已经定义了以下索引:

CREATE INDEX
    users_search_idx
ON
    auth_user
USING
    gin(
        username gin_trgm_ops,
        first_name gin_trgm_ops,
        last_name gin_trgm_ops
    );
Run Code Online (Sandbox Code Playgroud)

我正在执行以下查询:

PREPARE user_search (TEXT, INT) AS
    SELECT
        username,
        email,
        first_name,
        last_name,
        ( -- would probably do per-field weightings here
            s_username + s_first_name + s_last_name
        ) rank
    FROM
        auth_user,
        similarity(username, $1) s_username,
        similarity(first_name, $1) s_first_name,
        similarity(last_name, $1) s_last_name
    WHERE
        username % $1 OR
        first_name % $1 OR
        last_name % $1
    ORDER BY
        rank DESC
    LIMIT $2;
Run Code Online (Sandbox Code Playgroud)

auth_user表有620万行.

查询的速度似乎在很大程度上取决于查询可能返回的结果数similarity.

通过增加相似性阈值有set_limit帮助,但通过消除部分匹配来降低结果的有用性.

有些搜索在200ms内返回,其他搜索需要大约10秒. …

postgresql similarity trigram postgresql-9.6 pg-trgm

6
推荐指数
1
解决办法
2098
查看次数

Postgresql BTREE_GIN 索引带有 gin_trgm_ops 选项?

https://www.postgresql.org/docs/current/static/pgtrgm.html上,解释了如何使用带有 gin_trgm_ops 选项的特殊 GIN 索引来提高 trigram 相似性运算符的性能。

CREATE INDEX trgm_idx ON test_trgm USING GIN (t gin_trgm_ops);
Run Code Online (Sandbox Code Playgroud)

也有人说:

这些索引不支持相等或简单的比较运算符,因此您可能还需要常规 B 树索引。

然而,还有 BTREE_GIN 扩展,它应该允许 GIN 索引用作 BTREE 索引的替代品。https://www.postgresql.org/docs/current/static/btree-gin.html

我的问题是:如果我安装 BTREE_GIN 扩展,pg_trgm GIN 索引(带有 gin_trgm_ops 选项)可以用作 BTREE 索引的替代品吗?它是否结合了 BTREE_GIN 和 trigram GIN 索引的属性,或者仍然需要额外的 BTREE 索引来进行连接和相等表达式等?

postgresql gwt-gin b-tree postgresql-performance trigram

5
推荐指数
1
解决办法
2656
查看次数

Postgres Select ILIKE %text% 在大字符串行上运行缓慢

我有一个只有 7 列的表,其中一列存储每一行​​的长文本数据。该文本列数据的平均字符长度约为 1500 个字符。该表有 500.000 行。

当我使用选择查询而不使用该文本列时,没有问题,查询按预期需要 10 秒。

但是,如果我将这个长文本列添加到我的查询中,则Select * from table_1需要 3 或 4 分钟才能完成此查询并使用数据适配器填充数据表。

为什么我需要查找所有长文本列记录?因为我需要对其使用文本过滤器,例如:

SELECT * 
FROM table_1 
WHERE longtextcolumn ILIKE ANY (ARRAY['%texttosearch1%', '%texttosearch2%'])
Run Code Online (Sandbox Code Playgroud)

我应该做什么来加快这一进程?表分区可以解决这个速度问题吗?或者我应该寻找索引?

sql postgresql query-optimization database-indexes trigram

4
推荐指数
2
解决办法
6261
查看次数