当前位置: 首页 > 知识库问答 >
问题:

ElasticSearch:给ngrams赋分

饶谦
2023-03-14

我试图使用elasticsearch使用ngrams进行名称搜索匹配,我试图实现的技术如下:
输入:需要与数据库匹配的名称。
输出:来自我的名称数据库的所有潜在名称匹配。

我尝试这样做的方法如下:我将名称拆分为长度为3-5的ngrams。
然后我从数据库中收集所有与这些ngrams匹配的名称。
然后我检查ngrams并按反向频率对它们进行排序,
这意味着普通ngrams将得到最低的分数。
例如,如果我将它用于像“我的公司inc”这样的公司名称,我将给“inc”ngrams最低的分数,因为inc出现在许多公司名称中。

我计算分数的方法是:1/(计算ngram在我所有db中的出现),这样我将有“最强”的ngram作为出现最少的ngram。

我在python脚本中实现了这一点,但我想使用elastic的强大功能为我做同样的事情,
我知道ngram标记器,但有没有方法告诉他做我做的分数?
据我所知,当我现在进行匹配时,它将根据查询中的ngram与他在数据库中的单词中的ngram匹配多少来给结果打分

这是我使用的映射:

{
   "settings": {
       "analysis": {
           "analyzer": {
               "my_analyzer": {
                   "tokenizer": "my_tokenizer"
               }
           },
           "tokenizer": {
               "my_tokenizer": {
                   "type": "ngram",
                   "min_gram": 3,
                   "max_gram": 5,
                   "token_chars": ["letter", "digit"]
               }
           }
       }
   },  
   "mappings": {
       "names": {
           "properties": {
               "name": {
                   "type": "text",
                   "fields": {
                       "keyword": {
                           "type": "keyword",
                           "ignore_above": 256,
                        }
                   },
                   "analyzer": "my_analyzer"
              },
              "id": {
                 "type": "long"
               }
           }
       }
   }                  
}

这是我所做的查询:

GET /names/_search
{
 "query": {
   "match" : { "name" : "my company inc"}
 }
}

共有1个答案

郭永怡
2023-03-14

您希望使用的查询如下:

{
  "query": {
    "common": {
      "name": {
        "query": "my company inc",
        "cutoff_frequency": 0.001
      }
    }
  }
}

公共术语查询仅基于重要术语(重要ngram)即频率较低的术语返回相关性得分。在这里,文档频率大于0.1%的词将被认为是常用词,不会影响相关性得分。

或者,如果您已经有一个预定义的停止词列表(inc,pvt,ltd),那么您可以始终使用分析器中的自定义停止词过滤器来过滤它们以生成点击量。

{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer",
          "filter": [
            "custom_stop_token_filter"
          ]
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "ngram",
          "min_gram": 3,
          "max_gram": 5,
          "token_chars": ["letter", "digit"]
        }
      },
      "filter": {
        "custom_stop_token_filter": {
          "type": "stop",
          "stopwords": [
            "inc",
            "pvt",
            "ltd"
          ]
        }
      }
    }
  }
}
    null
 类似资料:
  • 我和dplyr一起工作,我有一个类似的小消息: 所以我可以对每个列使用ifelse函数和mutate: 但是在我真正的df中,我有很多列,那么这个wat是非常低效的。我需要一些更优雅的东西,使用mutate_at和列名,但这似乎很难。我试着用很多方法做到这一点,但每次我都会出错。有什么建议吗?

  • 我的代码是这样的: 但最后一句话: 总是停止编译说我需要给新变量分配一个返回值?在if语句之前,已经为k分配了一个值。当我把随机k语句放在if语句中时,它似乎是有效的,但这使得它毫无价值,不是吗?编辑器本身没有错误,但是当我编译时,它给了我这个: 线程“main”java中出现异常。lang.IndexOutOfBoundsException:索引:41,大小:36。util。ArrayList。

  • 只要一个动画,就可以带来生命。不幸的是,当设计师创建图标、logo 和吉祥物的时候,他们交付的通常都是图片或静态的 SVG。所以,虽然 GitHub 的章鱼猫、Twitter 的小鸟以及其它许多 logo 类似于生灵,它们看上去实际上并不是活着的。 Vue 可以帮到你。因为 SVG 的本质是数据,我们只需要这些动物兴奋、思考或警戒的样例。然后 Vue 就可以辅助完成这几种状态之间的过渡动画,来制作

  • 我正在将一个变量赋给一个数组,它是我在刀片文件中声明的。它返回一个错误 下面是我的代码: 我无法理解这个错误。谢谢!

  • 我想把列表中的对象分配给类变量。 感恩节:)

  • 可以编写认可字符串变元的MATLAB函数,而无须用括号或引号。也就是说,MATLAB把 foo a b c 理解为 foo('a','b','c') 然而,当用非引用形式时,MATLAB不能返回变元。例如, legend apples oranges 在一幅图创立一个图例并用字符串apples和oranges作为标签。若想legend命令返回它的输出变元,则必须用引号。 [legh,objh