弹性评分基于使用mvel的正则表达式

时间:2013-11-09 00:05:20

标签: php elasticsearch mvel elastica

我是弹性搜索新手,这是我想要解决的问题。 我有一个支持自动提供逻辑的搜索输入框。 结果取自使用ngram滤波器的弹性指数。 我想要改进的是引入评分能力,以便将结果从最重要的结果排序到不太重要的结果(取决于分数)。 分数必须基于以下情况:

  • 如果匹配以给定字符串开头,请设置分数100
  • 如果匹配包含给定字符串且未以该字符串开头,请将分数设置为10

为此目的,使用mvel语句实现了elastica脚本,以支持正则表达式匹配。换句话说,它检查左边的值是否与右边的正则表达式匹配(只有这时变量才相应增加)。但不幸的是,当搜索字符串是特定于语言时,它出错了,尽管左边的值也是指定的语言。另一个需要解决的问题是我上面提到的第二种情况(不能让它起作用)。

从给定单词('one')开始的值('一个示例'(属于名称字段))的脚本运行正常。

$testParam = mb_strtolower('one', 'utf-8');
$regexStart = '^' . $testParam . '.*$';
$ElasticaScript = new Elastica_Script(" total = 1; if(doc['name'].value ~= '{$regexStart}'){ total += 100; } return total; ");

当一个值('一个例子'(属于名称字段))包含给定单词('example')时的脚本不起作用,因此总得分保持为1并且不会增加到11,因为它应该是

$testParam = mb_strtolower('example', 'utf-8');
$regexStart = '^.*' . $testParam . '.*$';
$ElasticaScript = new Elastica_Script(" total = 1; if(doc['name'].value ~= '{$regexStart}'){ total += 10; } return total; ");

最后,以同样的逻辑,当我尝试将希腊词与名称字段的值(包含希腊字母)匹配时,总分的增量也会被忽略。

所有工作都是使用elastica完成的,更不用说php了。 你能帮忙解决我的问题吗? 如果有其他方法/解决方案,请随时与我分享。

提前谢谢

1 个答案:

答案 0 :(得分:0)

doc['name'].value加载分析的字段版本。除非您的字段设置为未分析,否则这可能与字段的原始内容非常不同,并且对于执行正则表达式匹配无用。 script fields上的Elasticsearch文档说这只适用于非分析或单项字段。例如,如果您的内容被索引为ngrams,则此值将包含ngrams。

您可以使用_source.field_name访问字段的原始文本,然后根据该字段计算得分。您仍然可以像往常一样针对ngrams进行搜索,并仅使用_source进行评分。

以下是一个示例function_score查询,默认分数为_score,如果名称字段以一个开头,则添加100,如果名称字段包含其他地方一个。它使用_source.name来访问名称字段的内容,因此它正在对名称字段的原始文本执行正则表达式,而不是从名称字段计算的ngrams。

{
  "query": {
    "function_score": {
      "boost_mode": "replace",
      "script_score": {
        "script": "total = _score; if (_source.name ~= '^one.*') { total += 100 } else if (_source.name ~= '.*?one.*?') { total += 10 } return total"
      }
    }
  }
}