我正在为ecomm网站构建一个由Elasticsearch驱动的分层导航模块。一切都很好,我可以从外部来源获取选项并显示它们。选择它们也可以,但是我遇到了一个麻烦,其中一个过滤器选项具有这些选择;
FINISHES:
Finished (1)
Semi-Finished (16)
Semi Finished (1)
很明显,应该整理带有和不带有连字符的2个变体,但是当我将以下内容应用于我的集合时,暂时忽略它;
$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条记录。毫无疑问,因为它们都包含被搜索“完成”的单词之一。
如何仅搜索确切的词?我曾尝试用\来对连字符进行转义,这无济于事,我还尝试检查搜索到的术语是否包含空格或连字符,并试图将其强制添加到“ must_not”中,但这也不起作用;
if(!$space) {
$params['body']['query']['bool']['must_not'][] = ['match' => [$split[0] => ' ']];
}
if(!$hyphen) {
$params['body']['query']['bool']['must_not'][] = ['match' => [$split[0] => '\\-']];
}
答案 0 :(得分:1)
默认情况下,标准分析仪应用于所有字段。因此,在您的情况下,Semi-Finished
是keyword
,倒排索引将包含两个单词semi
和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
}
]
}