0

我是弹性搜索的新手,这是我要解决的方案。我有一个支持自动建议逻辑的搜索输入框。结果是从使用 ngram 过滤器的弹性索引中获取的。我要改进的是引入评分功能,以便将结果从最重要的结果排序到次要的结果(取决于分数)。分数必须基于以下情况:

  • 如果存在以给定字符串开头的匹配项,则设置分数 100
  • 如果有一个匹配包含给定的字符串并且不以它开头,则将 score 设置为 10

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

以给定单词 ('one') 开头的值 ('one example' (属于 name 字段)) 的脚本工作得很好。

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

当值('一个示例'(属于名称字段))包含给定单词('示例')时的脚本不起作用,因此总分保持 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了。你能帮忙解决我的问题吗?如果有其他方法/解决方案,请随时与我分享。

先感谢您

4

1 回答 1

0

doc['name'].value加载字段的分析版本。除非您的字段设置为未分析,否则这可能与字段的原始内容有很大不同,并且对于进行正则表达式匹配没有用处。脚本字段上的 Elasticsearch 文档说这仅对非分析或单个术语字段有意义。例如,如果您的内容被索引为 ngram,则此值将由 ngram 组成。

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

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

{
  "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"
      }
    }
  }
}
于 2013-11-11T01:42:30.410 回答