如何在Elasticsearch中不匹配裸连字符?

时间:2017-10-23 15:43:35

标签: elasticsearch elastic-stack

我正在查询存储在Elasticsearch中的apache日志。我想从给定主机名返回日志条目,该主机名具有连字符和填充的auth字段。

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

我的问题是:

  1. 如何正确地重新映射Elasticsearch中的类型以允许连字符成为匹配字符串的一部分。
  2. 如何使用纯连字符正确查询Elasticsearch中的类型。
  3. 连字符是Elasticsearch中的保留字符,所以我理解它需要特别的努力。但是,我在查询如何将其包含在我的查询中时遇到了很多麻烦。

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

    以下是我重新映射的尝试:

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

    我没有包含auth字段的重新映射,因为它只返回mapper_parsing_exception

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

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

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

    我尝试过使用“term”而不是“match”;没有结果。

    我可以匹配“auth”的特定字符串,例如"must": { "match": { "auth": "foo" } }返回auth =“foo”的所有条目。这与我需要的相反,但确实有效。如果主机名包含连字符,则主机名仍然不完全匹配。

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

    我已经阅读了文档和示例,但还有很多需要深入研究。我发现的许多例子都是针对Elasticsearch的旧版本,这是可以理解的,但令人困惑。

    我是Elasticsearch的新手。感觉我只是在忽视某些事情,但问题可能源于对Elasticsearch如何做事的基本误解。

1 个答案:

答案 0 :(得分:0)

在ElascticSearch查询上花了一些时间之后,我想我已经弄明白了。

将主机名字符串拆分为两个单独的字符串,并且两者都匹配,以按预期过滤主机名。使用空字符串进行否定匹配似乎也按预期工作。

以下是更新的查询:

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

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

我努力让ElasticSearch符合我的预期。我没有和ElasticSearch合作,而是试图反对它。