【发布时间】:2019-01-28 19:43:50
【问题描述】:
如果我在“消息”字段中搜索包含例如“被调用”的文档,我会得到预期的结果,但是当我搜索“被调用”、“被调用*”或
"*was called*"
我什么也没得到,尽管我有很多文档,其消息字段包含以下内容“应用程序被 REST API 调用”。
这是我发送的查询的一部分:
"wildcard": {
"message": {
"wildcard": "was called",
"boost": 1.0
}
}
这是映射的一部分:
"mappings": {
"doc": {
"dynamic_templates": [
{
"message_field": {
"path_match": "message",
"match_mapping_type": "string",
"mapping": {
"norms": false,
"type": "text"
}
}
},
{
"string_fields": {
"match": "*",
"match_mapping_type": "string",
"mapping": {
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"norms": false,
"type": "text"
}
}
}
],
"properties": {
...
"message": {
"type": "text",
"norms": false
}
}
}
}
我搜索的索引是由 Logstash 自动创建的。
我在另一个领域也有类似的问题;我在该字段中有以下值:“NP-00121”。 *00121 有效,但 *-00121 无效。
编辑:还有一个示例:当我发送以下通配符查询时,我有一个包含“/api/v1/log/rest”、“/api/v1/log/notification”等的“requestUri”字段没有“/api/v1*”。
所以看起来在使用空格和破折号时会出现问题。谁能帮我解决这个问题?
【问题讨论】:
-
正如您在通配符查询文档中所读到的,将通配符用作前缀是一种非常糟糕的做法。您应该考虑使用 ngrams,这里有一个广泛的问答,展示了如何做到这一点(我曾经遇到过同样的问题):stackoverflow.com/questions/30666371/…
-
感谢您的回答,但我不知道您在哪里看到前缀。我相信 ngrams 不是解决方案。我可以使用带有 AND 运算符的匹配查询来代替通配符查询,但这不是一个很好的解决方案。现在我将添加另一个示例,可以进一步澄清我遇到的问题
-
使用通配符
*作为前缀(如*00121)是一种不好的做法,这就是我所指的。无论何时寻找部分单词,无论是在开头还是结尾,ngram 都是解决方案。 -
我想应该在 Elastic 搜索服务器上定义 ngram?我的索引是由 logstash 自动创建的(新的一天 - 新的索引)。
-
您可以定义一个index template,其中包含进行 ngram 标记化所需的分析器。因此,每天当 logstash 创建新索引时,可以将适当的索引设置/分析器应用于您的索引。
标签: elasticsearch lucene logstash