我有一个问题,我不确定我是否理解。我有以下用 PHP 编写的 Elasticsearch 查询,其模糊性匹配硬编码;这会产生大约 1,500 个预期搜索结果。
private function phraseQuery(array $matchFields): array {
return [
'bool' => [
"minimum_should_match" => 1,
"should" => [
$this->multiMatch($matchFields),
[
'match' => [
'Title' => [
'query' => $this->searchTerm,
'fuzziness' => 'AUTO:4,8'
]
]
], [
'match' => [
'TransliteratedTitle' => [
'query' => $this->searchTerm,
'fuzziness' => 'AUTO:4,8'
]
]
]
]
]
];
}
当我替换查询的“匹配”部分以使用函数动态生成时,我得到 4 个精确的搜索结果; Elasticsearch 似乎有效地忽略了模糊性查询。我已在 PHP Playground 上确认查询在结构上完全相同,但两个查询之间似乎存在差异。 PHP展开运算符不是这样工作的吗?
private function fuss(array $matchFields): array {
$fuzziness = [];
foreach($matchFields as $field) {
$query = ['query' => $this->searchTerm , 'fuzziness' => 'AUTO:4,8'];
$match = [ $field => $query ];
$fuzziness[] = [ 'match' => $match ];
}
return $fuzziness;
}
private function phraseQuery(array $matchFields): array {
return [
'bool' => [
"minimum_should_match" => 1,
"should" => [
$this->multiMatch($matchFields),
...$this->fuss($matchFields),
]
]
];
}
非常感谢任何帮助!
仅供参考:我正在使用 Elastic Cloud 和 PHP v8
我已经在 PHP Playground 上测试了我的代码,以确保对 Elasticsearch 的查询以完全相同的方式构建。我运行了两种形式的查询,一种返回 4 个结果,另一种返回近 1,500 个结果。
在 Barmar 的帮助下,我发现解决方案是生成字段名的方式。
乍一看,两个数组都使用了 Title 和 TransliteratedTitle 字段名称,但 Barmar 建议读取phraseQuery 本身的输出,这表明在一个函数中,我传入 Title 和 TransliteratedTitle 作为匹配的字段名称,而在另一个函数中(不起作用)函数 Title^100 和 TransliteratedTitle^100(^100 是为 ElasticSearch 提供权重的一部分)。
因此,正确的解决方案是:
"should" => [
$this->multiMatch($matchFields),
...$this->fuss($matchFields),
]
etc.
Elasticsearch 因此有效地忽略了两个不存在字段 Title^100 和 TransliteratedTitle^100 上的模糊查询。