与 Elastic Search 6 和 php ClientBuilder 进行精确匹配

Getting exact match with Elastic Search 6 and php ClientBuilder

我正在为一个 ecomm 站点构建一个由 elasticsearch 支持的分层导航模块。一切都很好,我可以从我的外部来源获取选项并显示它们。选择它们也有效,但我 运行 陷入困境,其中一个过滤器选项有这些选择;

FINISHES:

Finished (1)

Semi-Finished (16)

Semi Finished (1)

显然应该整理带连字符和不带连字符的 2 个变体,但是当我将以下内容应用于我的 collection;

时暂时忽略它
$client = $this->clientBuilder;
$params .... etc
$params['body']['query']['bool']['must'][] = ['match_phrase' => [$split[0] => "$selected"]];
$response = $client->search($params);

其中 $split[0] 是 'FINISHES' 的 elasticsearch 字段引用,$selected 是选择的值。如果您单击任何选项,我将取回所有 18 条记录。毫无疑问,因为它们都包含正在搜索的单词之一 'finished'。

如何才能使此搜索只搜索确切的字词?我试过用 \- 转义连字符,但没有用,我也试过检查搜索的词是否有空格或连字符,并试图将它们强行添加到 'must_not',但这也没有用;

if(!$space) {
    $params['body']['query']['bool']['must_not'][] = ['match' => [$split[0] => ' ']];
}
if(!$hyphen) {
    $params['body']['query']['bool']['must_not'][] = ['match' => [$split[0] => '\-']];
}

默认情况下,标准分析器应用于所有字段。因此,在您的情况下,Semi-Finishedkeyword 并且倒排索引将包含两个词 semifinished,因此每次您查找 finished 它都会匹配,因为标准分析器会中断它在连字符上。

POST _analyze
{
  "analyzer": "standard",
  "text": ["Semi-Finished"]
}

##Result
{
  "tokens" : [
    {
      "token" : "semi",
      "start_offset" : 0,
      "end_offset" : 4,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "finished",
      "start_offset" : 5,
      "end_offset" : 13,
      "type" : "<ALPHANUM>",
      "position" : 1
    }
  ]
}

.keyword 搜索原始文本,即未分析。在您的情况下,fieldname.keyword 应该有效。

POST _analyze
{
  "analyzer": "keyword",
  "text": ["Semi-Finished"]
}

##Result
{
  "tokens" : [
    {
      "token" : "Semi-Finished",
      "start_offset" : 0,
      "end_offset" : 13,
      "type" : "word",
      "position" : 0
    }
  ]
}