基于匹配token比率的Elasticsearch评分

Posted

技术标签:

【中文标题】基于匹配token比率的Elasticsearch评分【英文标题】:Elasticsearch scoring based on the ratio of the matched tokens 【发布时间】:2016-04-19 09:07:26 【问题描述】:

我正在使用 Elasticsearch(v 1.7.3,带有 Java 传输客户端)来搜索人名数据库。我正在利用一堆可用的语音算法(DoubleMetaphone、RefinedSoundex 等)来索引我的姓名字段并存储它们。但是,我需要的评分算法是计算输入标记与索引中的标记的接近百分比。

例如:

使用语音算法对以下文档进行索引时:


  "FullName": "Christopher Cruickshank"

扩展为(使用分析 api 获取的输出):


  "tokens": [
    
      "token": "C3090360109",
      "start_offset": 0,
      "end_offset": 11,
      "type": "<ALPHANUM>",
      "position": 1
    ,
    
      "token": "christopher",
      "start_offset": 0,
      "end_offset": 11,
      "type": "<ALPHANUM>",
      "position": 1
    ,
    
      "token": "K3936",
      "start_offset": 0,
      "end_offset": 11,
      "type": "<ALPHANUM>",
      "position": 1
    ,
    
      "token": "KRST",
      "start_offset": 0,
      "end_offset": 11,
      "type": "<ALPHANUM>",
      "position": 1
    ,
    
      "token": "C3903083",
      "start_offset": 12,
      "end_offset": 23,
      "type": "<ALPHANUM>",
      "position": 2
    ,
    
      "token": "cruickshank",
      "start_offset": 12,
      "end_offset": 23,
      "type": "<ALPHANUM>",
      "position": 2
    ,
    
      "token": "K3935",
      "start_offset": 12,
      "end_offset": 23,
      "type": "<ALPHANUM>",
      "position": 2
    ,
    
      "token": "KRKX",
      "start_offset": 12,
      "end_offset": 23,
      "type": "<ALPHANUM>",
      "position": 2
    
  ]

现在在搜索期间,当我查询:


              "match": 
                "FullName": 
                  "query": "Cristopher Krukshank",
                  "boost": 10.0
                
              
            

我想做的是根据索引中匹配标记的数量对结果进行评分。

即:

(Number of matched tokens per term / Total number of expanded tokens per term) * Boost

虽然这在概念上可行,但我想知道是否有更好的方法来实现同样的效果。

另外,我倾向于在索引期间增加很多复杂性和逻辑(通过将总标记数存储在字段中),因此我的搜索逻辑会更简单。如果这是一种合理的方法,那么我想知道在索引过程中使用分析 api 是否有任何技术含义,尤其是在对数百万个名称使用批量索引时。 我猜会为每个原始令牌和每个扩展令牌(可能很大!)调用分析 API。

如果这根本不是一个合理的方法,那么请有人指点或分享一些经验吗?

我也在考虑的另一个选项是在查询期间调用分析 api,并使用“解释”选项将查询发送到 elasticsearch,然后在解释部分进行字符串匹配以计算出匹配的令牌数。

【问题讨论】:

你的意思是不是和我在***.com/questions/39100218/…中描述的类似 你能解决这个问题吗?我不想在搜索之前通过调用分析 API 添加另一个网络调用 【参考方案1】:

我们以间接的方式做到了这一点。我正在努力寻找更好的方法并看到了您的帖子。

解决方案是在搜索“Cristopher Krukshank”时,例如,第一个命中是:

Cristopher Krukshank Jr.”,得分为 10.0

然后您获取第一个结果“Cristopher Krukshank Jr.”并再次搜索。当然,第一个结果将是“Cristopher Krukshank Jr.”,但得分更高,例如“20.0”。

所以你知道最高分数是20,那么对于部分匹配,最终分数是“first score/max score”,即10/ 20 = 0.5。最终得分将是一个介于 0~1 之间的值。 1 表示完全匹配。

一个问题是输入可能是一个标记任何东西。例如,对于“Cristopher Krukshank XXXXX”,XXXXX 可能不是索引上的标记。所以为了让它正确,我们必须使用令牌的数量来重新计算分数。

【讨论】:

以上是关于基于匹配token比率的Elasticsearch评分的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch Analyzer详解

基于token的身份验证-2.0版本

es中的analyzer,tokenizer,filter你真的了解吗?

6、ElasticSearch添加密码验证机制(规避了诸多小坑的操作步骤)

Elasticsearch:词分析中的 Normalizer 的使用

Elasticsearch:文本分析器剖析