我如何不匹配 Elasticsearch 中的连字符?

How do I not match a bare hyphen in Elasticsearch?

我正在查询存储在 Elasticsearch 中的 apache 日志。我想 return 记录来自给定主机名的条目,该主机名带有连字符并填充了验证字段。

这些字符串应该完全匹配:"hostname": "example-dev" 而不是 "auth": "-"

我的问题是:

  1. 如何正确地重新映射 Elasticsearch 中的类型以允许连字符成为匹配字符串的一部分。
  2. 如何使用连字符在 Elasticsearch 中正确查询类型。

连字符是Elasticsearch中的保留字符,所以我知道这需要特别的努力。但是,我在弄清楚如何将它包含在我的查询中时遇到了很多麻烦。

我试图将类型重新映射为 not_analysed。看起来格式最近发生了变化。定义索引("analysed""not_analysed""no")的旧方法对我来说很有意义。新方法(truefalse)不会。在任何一种情况下,我似乎都无法重新映射工作。

这是我重新映射的尝试:

DELETE /search
PUT search
{
    "mappings" : {
        "beat" : {
            "properties" : {
                "hostname" : {
                    "type" : "text",
                    "norms" : false,
                    "index" : false
                }
            }
        }
    }
}

我没有包括 auth 字段的重新映射,因为它只是 return 一个 mapper_parsing_exception

我正在使用 json 查询 Elasticsearch。这是我的查询:

GET _search
{
    "query": {
        "bool": {
            "filter": {
                "bool": {
                    "must": [
                        {
                            "match": {
                                "beat.hostname": "example-dev"
                            }
                        }
                    ],
                    "must_not": [
                        {
                            "match": {
                                "auth.keyword": "-"
                            }
                        }
                    ]
                }
            }
        }
    }
}

我尝试用 \- 转义连字符,但 return 的结果与 "auth": "-" 匹配。主机名仍然不完全匹配。主机名查询也匹配 "example-prod".

我试过使用 "term" 而不是 "match"; return没有结果。

我可以为 "auth" 匹配一个特定的字符串,例如 "must": { "match": { "auth": "foo" } } returns all entries for auth = "foo"。这与我需要的相反,但它确实有效。如果包含连字符,主机名仍然不完全匹配。

使用 ELK 堆栈将日志条目解析到 Elasticsearch 中,但是由于遗留原因,这将是在 Kibana 外部生成的报告。

我已经阅读了文档和示例,但是还有很多东西需要挖掘。我找到的许多示例都是针对旧版本的 Elasticsearch 的,这是可以理解的,但令人困惑。

我是 Elasticsearch 的新手。感觉我只是忽略了一些东西,但问题可能源于对 Elasticsearch 如何做事的基本误解。

在 ElascticSearch 查询上花费了更多时间后,我想我明白了。

将主机名字符串拆分为两个单独的字符串并匹配这两个字符串以按预期过滤主机名。对否定匹配使用空字符串似乎也能按预期工作。

这是更新后的查询:

{
"query": {
    "bool": {
        "filter": {
            "bool": {
                "must": [
                    {
                        "match": {
                            "beat.hostname": "example"
                        }
                    },
                    {
                        "match": {
                            "beat.hostname": "dev"
                        }
                    }
                ],
                "must_not": [
                    {
                        "match_phrase": {
                            "auth.keyword": ""
                        }
                    }
                ]
            }
        }
    }
}

我会做更多的测试,以确保这实际上返回了我需要的东西。

我太过努力让 ElasticSearch 符合我的预期。我没有使用 ElasticSearch,而是试图与之抗争。