如何在关键字字段 Elasticsearch Query 6.4.2 上执行反匹配模式

Posted

技术标签:

【中文标题】如何在关键字字段 Elasticsearch Query 6.4.2 上执行反匹配模式【英文标题】:How do I do an Anti Match Pattern on Keyword Field Elasticsearch Query 6.4.2 【发布时间】:2019-06-14 23:41:34 【问题描述】:

问题:

我们的日志数据有 27-34 百万个 /event-heartbeat 条目。 我需要过滤掉这些条目,以便在 Kibana 中查看可行的日志消息。

使用带有通配符的 Kibana 过滤器不起作用。因此,我认为我必须在 6.4.2 版本的 Elasticsearch 中编写 QueryDSL 才能过滤掉事件心跳。

我一直在寻找,但找不到任何关于如何进行反模式匹配的好的解释,以便搜索消息中没有 /event-heartbeat 的所有条目。

这是日志消息:

@timestamp:
    June 14th 2019, 12:39:09.225
host.name:
    iislogs-production
source:
    C:\inetpub\logs\LogFiles\W3SVC5\u_ex19061412.log
offset:
    83,944,181
message:
    2019-06-14 19:39:06 0.0.0.0 GET /event-heartbeat id=Budrug2UDw 443 - 0.0.0.0 - - 200 0 0 31
prospector.type:
    log
input.type:
    log
beat.name:
    iislogs-production
beat.hostname:
    MYHOSTNAME
beat.version:
    6.4.2
_id:
    yg6AV2sB0_n
_type:
    doc
_index:
    iislogs-production-6.4.2-2019.06.14
_score:
    - 

Message 是一个关键字字段,因此我可以对其进行轻松的脚本编写。

我用过 Lucene 语法

NOT message: "*/event-heartbeat*"

This is the anti pattern the kibana filter generates.

  "query": 
    "bool": 
      "should": [
        
          "match_phrase": 
            "message": "*event-heartbeat*"
          
        
      ],
      "minimum_should_match": 1
    
  

我已经尝试了以下由 huglap 提出的解决方案。我还根据他的评论调整了我的查询,并尝试了两种方法。我用词而不是匹配来调整它,并尝试了两种方式,因为从技术上讲,该字段是一个关键字,所以我可以对其进行轻松的脚本编写。该查询仍会返回事件心跳日志条目。

这是我从以下建议的解决方案中尝试的两个查询:

GET /iislogs-production-*/_search

   "query":
      "bool":
         "must":
            "match_all":

            
         ,
         "filter":
            "bool":
               "must_not":[
                  
                     "term":
                        "message.whitespace":"event-heartbeat"
                     
                  
               ]
            
         
      
   


GET /iislogs-production-*/_search

   "query":
      "bool":
         "must":
            "match_all":

            
         ,
         "filter":
            "bool":
               "must_not":[
                  
                     "match":
                        "message.whitespace":"event-heartbeat"
                     
                  
               ]
            
         
      
   

索引映射: https://gist.github.com/zukeru/907a9b2fa2f0d6f91a532b0865131988

【问题讨论】:

【参考方案1】:

您是否考虑过“must_not”布尔查询? 由于您要使用整个集合并且并不真正关心塑造相关性功能,因此我建议使用过滤器而不是查询。您将获得更好的性能。


   "query":
      "bool":
         "must":
            "match_all":

            
         ,
         "filter":
            "bool":
               "must_not":[
                  
                     "match":
                        "message.whitespace":"event-heartbeat"
                     
                  
               ]
            
         
      
   

此示例假设您正在查询文本字段,因此使用“匹配”查询而不是“术语”查询。 您还需要确保根据您的目标对该字段进行分析(真正标记化)。如果您使用的是简单的甚至是标准的分析器,您的查询词中有破折号这一事实会产生问题。 Elasticsearch 会将这个词分成两个词。您可以在那个上尝试空白分析器,或者只是从查询中删除破折号。

【讨论】:

我用 MATCH 和 TERM 都试过了,因为从技术上讲,它是一个关键字字段,所以我可以在它上面直接编写脚本来提取 IP,它可以工作,但仍然返回带有 /event-heartbeat 的值.我将为您描述它并更新问题。 @拥抱

以上是关于如何在关键字字段 Elasticsearch Query 6.4.2 上执行反匹配模式的主要内容,如果未能解决你的问题,请参考以下文章

elasticsearch的keyword与text的区别

Elasticsearch 聚合功能

在elasticsearch中搜索多个字段作为正则表达式查询

Elasticsearch 字段类型

ElasticSearch多个字段分词查询高亮显示

elasticsearch 特殊字段