elasticsearch ngram 和 postgresql trigram 搜索结果不匹配

Posted

技术标签:

【中文标题】elasticsearch ngram 和 postgresql trigram 搜索结果不匹配【英文标题】:elasticsearch ngram and postgresql trigram search results are not match 【发布时间】:2017-12-21 22:51:21 【问题描述】:

我在 elasticsearch 上创建了一个索引,如下所示:

"settings" : 
    "number_of_shards": 1,
    "number_of_replicas": 0,
    "analysis": 
                "filter": 
                    "trigrams_filter": 
                        "type":     "ngram",
                        "min_gram": 3,
                        "max_gram": 3
                    
                ,
                "analyzer": 
                    "trigrams": 
                        "type":      "custom",
                        "tokenizer": "standard",
                        "filter":   [
                            "lowercase",
                            "trigrams_filter"
                        ]
                    
                
    
,
"mappings": 
    "issue": 
        "properties": 
            "description": 
                "type":     "string",
                "analyzer": "trigrams"
            
        
    

我的测试项目如下:

"alici onay verdi basarili satisiniz gerceklesti diyor ama hesabima para transferi gerceklesmemis"

"otomatik onay işlemi gecikmiş"

"************* nolu iade islemi urun kargoya verilmedi zamaninda iade islemlerinde urun erorr hata veriyor"

我用下面的查询测试了这个索引:

GET issue/_search

  "query": 
      "match": 
            "description":
                 "query": "otomatik onay istemi zamaninda gerceklesmemis"
            
       
   

结果:


      ....
      "hits": 
            ....
                "max_score": 2.3507352,
                "hits": [
                          
                              ....                                   
                              "_score": 2.3507352,
                              "_source": 
                                   "issue_id": "*******",
                                   "description": "alici onay verdi basarili satisiniz gerceklesti diyor ama hesabima para transferi gerceklesmemis"
                                          
                           
                        ]
                
 

postgresql 上的相同数据具有以下 SQL 响应另一个结果:

SELECT 
     public.tbl_issue_descriptions_big.description,
     similarity(description, 'otomatik onay islemi zamaninda gerceklesmemis') AS sml
FROM
     public.tbl_issue_descriptions_big
WHERE
     description %'otomatik onay islemi zamaninda gerceklesmemis'
ORDER BY
     sml DESC
LIMIT 10

结果是:

description                                           | sml
======================================================|======
otomatik onay islemi gecikmis                         |0,351852

为什么会出现这种差异?

【问题讨论】:

您的问题解决了吗?我很好奇,我发现 PostgreSQL 开箱即用更准确。 不,我没有解决问题。因为 Postgresql 通过 tf/idf 相似性机制计算,但 ElasticSearch 使用 BM25。也许您可以更改 ElasticSearch 上的相似性机制。但不要在 Postgresql 上。也许你可以使用三十方 pgPLSQL 函数或 Python。 【参考方案1】:

我对 postgres 的了解不够,无法在那里给出一个合格的答案(因为这也取决于被索引的文档以及它们的评分公式是否完全相同,我对此表示怀疑),但 Elasticsearch 有一个 explain API 和一个explain parameter 在搜索中,帮助您找出为什么某个文档会以这种方式评分。

【讨论】:

感谢您的回答。但我认为解释 postgresql 等价的是 ts_vector 并用于全文搜索。但是 ngram 和相似性用于机器学习。我现在在 elasticsearch 上搜索相似度算法。 查看 lucene 文档,例如 lucene.apache.org/core/6_6_0/core/org/apache/lucene/search/… 或 lucene.apache.org/core/6_6_0/core/org/apache/lucene/search/…(如果您创建新索引,则从 ES 5.0 开始默认设置)

以上是关于elasticsearch ngram 和 postgresql trigram 搜索结果不匹配的主要内容,如果未能解决你的问题,请参考以下文章

如何在Elasticsearch中使用ngram时控制结果的评分或排序?

[Elasticsearch] 部分匹配 - 索引期间优化ngrams及索引期间的即时搜索

[Elasticsearch] 部分匹配 - 索引期间优化ngrams及索引期间的即时搜索

Elasticsearchngram 分词器

Elasticsearch 荧光笔误报

Elasticsearch:使用 search_analyzer 及 edge ngram 来实现 Search-As-You-Type