2015-09-20 95 views
0

我在Go中進行編程時一直保持不變。如何在彈性搜索中搜索Go按時間框架篩選結果

我想創建一個簡單的程序,只有一件事通過elasticsearch API搜索字符串。 我的問題是特定於我使用的「gopkg.in/olivere/elastic.v2」包。

下面是一個代碼示例:

package main 

import (
    "fmt" 
    "gopkg.in/olivere/elastic.v2" 
    "log" 
    "reflect" 
) 

type Syslog struct { 
    Program string 
    Message string 
    Timestamp string 
} 


func main() { 

    client, err := elastic.NewClient(elastic.SetURL("http://localhost:9200")) 
    if err != nil { 
     log.Fatal(err) 
    } 
    info, code, err := client.Ping().Do() 
    if err != nil { 
     log.Fatal(err) 
    } 
    fmt.Printf("Elasticsearch returned with code %d and version %s", code, info.Version.Number) 

    termQuery := elastic.NewTermQuery("message", "configuration") 

    searchResult, err := client.Search(). 
     //PostFilter(postFilter). 
     Index("logstash-*").  // search in index "logstash-*" 
     Query(&termQuery).  // specify the query 
     Sort("timestamp", true). // sort by "message" field, ascending 
     From(0).Size(10).  // take documents 0-9 
     Pretty(true).   // pretty print request and response JSON 
     Do()      // execute 
    if err != nil { 
     log.Fatal(err) 
    } 
    fmt.Printf(" Query took %d milliseconds\n", searchResult.TookInMillis) 

    var ttyp Syslog 

    for _, item := range searchResult.Each(reflect.TypeOf(ttyp)) { 
     t := item.(Syslog) 
     fmt.Printf("Found %s %s %s\n", t.Timestamp, t.Program, t.Message) 
    } 

} 

這工作,但我真正想要的是時間範圍來限制搜索。

據我所知,我需要使用FilteredQuery函數。但我迷失在試圖找出如何創建一個過濾的查詢。

有創建它的函數「FilteredQuery」它需要查詢類型作爲輸入參數,但沒有創建查詢本身的函數。我可以只創建一個所需類型的變量,但它仍然需要具有類似於elasticsearch中查找的字段和要查找的字符串的字段。

在調用func (FilteredQuery) Filter時,Filter變量的作用相同。

可能有人已經有了一個例子,或者可以指引我走向正確的方向。

我有如果傳遞給elastcisearch一個JSON的例子讓我我想要的:

"query": { 
    "filtered": { 
     "query": { 
     "query_string": { 
      "query": "message:\"configuration\"", 
      "analyze_wildcard": true 
     } 
     }, 
     "filter": { 
     "bool": { 
      "must": [ 
      { 
       "range": { 
       "@timestamp": { 
        "gte": 1442100154219, 
        "lte": 1442704954219 
       } 
       } 
      } 
      ], 
      "must_not": [] 
     } 
     } 
    } 
    }, 

但我不知道如何實現在走同樣的。謝謝。

回答

1

RangeFilterFilteredQuery

這裏是產生你想要的結果的一個例子:

package main 

import (
    "encoding/json" 
    "fmt" 

    elastic "gopkg.in/olivere/elastic.v2" 
) 

func main() { 

    termQuery := elastic.NewTermQuery("message", "configuration") 

    timeRangeFilter := elastic.NewRangeFilter("@timestamp").Gte(1442100154219).Lte(1442704954219) 

    // Not sure this one is really useful, I just put it here to mimic what you said is the expected result 
    boolFilter := elastic.NewBoolFilter().Must(timeRangeFilter) 

    query := elastic.NewFilteredQuery(termQuery).Filter(boolFilter) 

    queryBytes, err := json.MarshalIndent(query.Source(), "", "\t") 
    if err != nil { 
     panic(err) 
    } 

    fmt.Println(string(queryBytes)) 
} 

它產生的輸出是:

{ 
    "filtered": { 
     "filter": { 
      "bool": { 
       "must": { 
        "range": { 
         "@timestamp": { 
          "from": 1442100154219, 
          "include_lower": true, 
          "include_upper": true, 
          "to": 1442704954219 
         } 
        } 
       } 
      } 
     }, 
     "query": { 
      "term": { 
       "message": "configuration" 
      } 
     } 
    } 
}