从elasticsearch获取单个字段中的匹配数

时间:2016-08-12 01:59:55

标签: elasticsearch elasticsearch-plugin

我想获取一个词在我的一个点击中与搜索结果一起出现的匹配数。 (例如,我想知道“hello”出现在“hello hi hello”2次)。

然而,我的问题甚至更棘手,因为我想使用soundex作为过滤器。(例如,如果我搜索“great”并且它与“test test grate that great”相匹配。然后我想知道我的比赛出现了2次,因为“伟大的”在语音上是相同的“格栅”

以下是我的索引:

{
    "lecture" : {  
        "properties" : {  
            "transcript" : {  
                "type" : "string",
                "analyzer" : "lecture_analyzer"
             },
            "file_id" : {
                "type" : "string"
            }
        }
    }
}

lecture_analyzer看起来像这样:

{
    "tokenizer":  "standard",
    "filter": [
        "dbl_metaphone",
    ]
}

dbl_metaphone是我用于phonetic matching

的内容

现在,当我发出以下查询时:

"query" : {
    "bool" : {
         "must" : [
              {"match": { "transcript" :"grate"}},
              {"term": { "file_id" : "21648371" }}
         ]
     }
}

我得到以下结果:

{
  ...
  "hits" : {
    "total" : 1,
    "max_score" : 3.519093,
    "hits" : [ {
      ...
      "_id" : "21648371",
      "_score" : 3.519093,
      "_source" : {
        "transcript" : "ok that's great, grate that carrot please",
        "file_id" : "21648371"
      }
    } ]
  }
}

然而,我想知道我的名字“炉排”在我的热门中出现了两次:一次用于“炉排”,一次用于“好”由于我使用的dbl_metaphone过滤器。

有谁知道怎么做?

1 个答案:

答案 0 :(得分:0)

这不是那么棘手,而是简单的术语计数问题。 首先,你必须检查"伟大"和"炉排"被翻译为使用双metaphone的术语。

$ curl -s 'http://<HOST>/<INDEX>/_analyze?analyzer=lecture_analyzer&pretty' \
-d "ok that's great, grate that carrot please" \
| grep '"token"'

你得到了

"token" : "AK",
"token" : "0TS",
"token" : "TTS",
"token" : "KRT",
"token" : "KRT",
"token" : "0T",
"token" : "TT",
"token" : "KRT",
"token" : "PLS",

所以你可以看到&#34;伟大&#34;,&#34;炉排&#34;还有&#34;胡萝卜&#34;被编码为&#34; KRT&#34;使用双metaphone。

接下来,如何计算文档中的匹配数对于Elasticsearch来说不是那么容易的问题。

一种方法是使用Script Field。使用Groovy作为脚本语言时,您可以通过_index[FIELD][TERM].tf()获得术语频率。

请注意,您必须在script.engine.groovy.inline.search: on中设置elasticsearch.yml以启用groovy脚本。

参考:ScriptingAdvanced Scripting

这是实际的查询。

{"query":{
    ... WRITE_YOUR_QUERY_HERE ...
  },
 "script_fields":{
   "transcript_count":{
     "script":"_index['transcript']['KRT'].tf()"
   }
 }
 "_source":["*"],
}

你得到像

这样的东西
"fields":{
  "transcript_count":[3]
}

第二种方法,不使用groovy,使用术语向量。

细节写在下面的问题中,所以我会省略。 How can I get total count of each words in elasticsearch document?

第三种方法是使用Explain API。由于您使用{"match": { "transcript" :"grate"}}进行搜索,因此您可以在搜索结果中使用Explain API获得以下内容。

"description" : "tf(freq=3.0), with freq of:",
"details" : [ {
"value" : 3.0,
"description" : "termFreq=3.0",
"details" : [ ]
} ]

它显示了如何计算得分的详细信息,以及 术语频率&#34; KRT&#34;显示在中间结果中。

出于安全原因,第一种方法并不是那么好。第二和第三对表现不太好。 为了实现安全性和性能,您可能需要编写自己的插件。见Native Java Scripts