java中的Elasticsearch正则表达式查询无法按预期工作

时间:2017-09-19 10:05:06

标签: java regex elasticsearch

我有一个Java应用程序,用于检索存储在ElasticSearch中的日志。 日志存储方式如下(这是您从ElasticSearch检索的内容):



{
	"took":1013,
	"timed_out":false,
	"_shards":{"total":40,"successful":40,"failed":0},
	"hits":{"total":28,"max_score":null,"hits":
    [
      {
      "_shard":"[logstash-2017.09.06][0]",
      "_node":"_G934CTGTjKypnI_D1b1Lg",
      "_index":"logstash-2017.09.06",
      "_type":"logs",
      "_id":"AV5WyiTlbV8ga6rEI4b8",
      "_score":null,
      "_source":{"@timestamp":"2017-09-06T10:44:01.691Z",
      "@version":"1",
      "message":"{
        \"log\":\"2017-09-19 09:26:09,149 INFO [com.mycompany.class.MyClass] (default task-23) Some log to retrieve\",
        \"stream\":\"stderr\",
        \"docker\":{
            \"container_id\":\"61b34e11002c636b289e7c40d6fbc6718e0deec58bf8a3410d598e3bd561672d\"
            },
        \"metadata\":{
            \"container_name\":\"router\",
            \"namespace_name\":\"default\",
            \"cluster_name\":\"cluster\"
            }
         }"
      },
      "sort":[1504694641691]
      }
    ]
  }
}




要仅获取包含单词' INFO'的日志,我想查询"消息",但日志在\" log \中",我只想查询\" log \"内的单词。

我想如果我查询" message.log"它可以工作,但它没有。它不是嵌套的json(" message":{key:value,key:value}),它是" message":" {string} " (有双引号):_(

如果存储的日志类似于" log":"日志"没有别的,但我无法改变将日志放入ElasticSearch的logstash的行为。

所以我尝试使用正则表达式(QueryBuilders.regexpQuery(" message"," Some_regex"))和以下正则表达式:

.*\"log\\\":\\\".*INFO.*},\\\"metadata\\\":{

我知道这个正则表达式也会影响\" stream \"或\#34; docker \",但它不是问题。

我在http://regexr.com/https://regex101.com/中对此正则表达式进行了测试,它应该可以正常运行,但是当我执行查询时,我会找到0个结果(并且应该有结果)。

我试用错误测试了更多正则表达式,但是如果我在

之后添加了任何内容,它就没有找到结果
.*\"log\\\":\\\".*INFO

我不习惯正则表达式,我确实希望在没有你帮助的情况下成功完成它,但我现在有点迷失了......

提前谢谢你,抱歉我的英语不好。谢谢!

1 个答案:

答案 0 :(得分:-1)

Here是在INFO部分之后对内容进行分组的一个正则表达式:

.*\\"log\\":\\".* INFO (.*)

说明:   - 匹配一个反斜杠需要\\   - 括号(.*)用于分组。您可以稍后检索它们。

java中的用法有点棘手。即如果你想把这个字符串指定为java String literal,那么你得到这个:

String str = "\"message\":\"{\"\r\n\\\"log\\\":\\\"2017-09-19 09:26:09,149 INFO [com.mycompany.class.MyClass] (default task-23) Some log to retrieve\\\",";

看起来很奇怪,但你总是可以测试我是否正确地逃脱了它们:

System.out.println(str);

所以,这是如何在java中使用这个正则表达式:

    // lots of escape characters :(
    // you can reuse the compiled pattern
    Pattern p = Pattern.compile(".*\\\\\\\"log\\\\\\\":\\\\\\\".* INFO (.*)");
    // this is how you match
    Matcher m = p.matcher(str);
    if (m.find()) {
        // this is how you retrieve the text after INFO
        System.out.println(m.group(1));
    } else {
        System.out.println("--> no match");
    }