1. 基本概念
1.1 index(索引)
在Elasticsearch中索引(index)相似mysql的表,代表文档数据的汇合,文档指的是ES中存储的一条数据。
1.2 Document(文档)
Elasticsearch是面向文档的数据库,文档是最根本的存储单元,文档相似mysql表中的一行数据。简略的说在ES中,文档指的就是一条JSON数据。
1.3 Field(文档字段)
文档由多个json字段(Field)组成, 这里的字段相似mysql中表的字段。
1.4 mapping (映射)
Elasticsearch的mapping (映射)相似mysql中的表构造定义,每个索引都有一个映射规定,咱们能够通过定义索引的映射规定,提前定义好文档的json构造和字段类型,如果没有定义索引的映射规定,Elasticsearch会在写入数据的时候,依据咱们写入的数据字段揣测出对应的字段类型,相当于主动定义索引的映射规定。
类比MYSQL存储构造:
元数据的字段名都是以下划线结尾的
常见的元数据如下:
- _index - 代表以后JSON文档所属的文档名字
- _type - 代表以后JSON文档所属的类型,尽管新版ES废除了type的用法,然而元数据还是能够看到
- _id - 文档惟一Id, 如果咱们没有为文档指定id,零碎会主动生成
- _source - 代表咱们插入进去的JSON数据
- _version - 文档的版本号,每批改一次文档数据,字段就会加1,这个字段新版的ES曾经不应用了
- _seq_no - 文档的版本号, 代替老的_version字段
- _primary_term - 文档所在主分区,这个能够跟_seq_no字段搭配实现乐观锁
开发实战:
第三方开发者保护的库 olivere/elastic
官网的Golang客户端 go-elasticsearch
olivere/elastic 应用
package mainimport ( "context" "fmt" "github.com/olivere/elastic/v7" "log" "os" "reflect" "time")// 查问后果定义type QueryInfo struct { Domain string `json:"domain"` // 查问域名 ClientIP string `json:"client_ip"` // 起源IP Scheme string `json:"scheme"` // 协定类型 Referer string `json:"referer"` // 申请起源 Url string `json:"url"` // 申请url HttpCode string `json:"http_code"` // 返回状态码 Method string `json:"method"` // 申请办法}// 初始化变量var ( queryInfo QueryInfo indexName = "chegva_ngx_proxy_log" // es集群地址列表:https://sgp.api.es.che/product/es/cluster-list apiAddresses = []string{"http://sgp.api.es.che"} // elasticsearch 服务地址,多个服务地址应用逗号分隔 username, password = "anzhihe", "anzhihe" client *elastic.Client res *elastic.SearchResult err error ctx context.Context)func init() { // 连贯es集群 client, err = elastic.NewClient( elastic.SetURL(apiAddresses...), elastic.SetBasicAuth(username, password), // 容许您指定弹性是否应该定期检查集群(默认为真) elastic.SetSniff(false), // 设置监控查看工夫距离 elastic.SetHealthcheckInterval(10*time.Second), // 设置谬误日志输入 elastic.SetErrorLog(log.New(os.Stderr, "ELASTIC ", log.LstdFlags)), // 设置info日志输入 elastic.SetInfoLog(log.New(os.Stdout, "", log.LstdFlags))) if err != nil { fmt.Println("连贯失败:%v\n", err) panic(err) } fmt.Println("连贯胜利", client)}// 查问日志func Search() { // 执行ES申请须要提供一个上下文对象 ctx = context.Background() // 创立bool组合查问;must条件相似SQL的and;must_not与must作用相同;should相似SQL中的or,只有匹配区中一个就行 //boolQuery := elastic.NewBoolQuery().Must() // 创立查问 // term准确查问;terms多值查问相似SQL的in查问 domainQuery := elastic.NewTermQuery("domain", "api.pay.chegva.com") // Match查问,匹配单个字段 urlQuery := elastic.NewMatchQuery("url", "/pay/") // Ranges范畴查问 timeQuery := elastic.NewRangeQuery("timestamp"). Gte("2022-02-22"). Lte("now"). Format("yyyy-MM-dd") // Filter 多重条件筛选 boolSearch := elastic.NewBoolQuery(). Filter(domainQuery). Filter(urlQuery). Filter(timeQuery) // 设置bool查问的must条件, 组合了两个子查问 //boolQuery.Must(domainQuery, timeQuery) res, err = client.Search(). Index(indexName). Query(boolSearch). From(0).Size(10). // 拿前10个后果,默认不能大于10000 Pretty(true). Do(ctx) // 执行 if err != nil { panic(err) } total := res.TotalHits() fmt.Printf("Found %d results\n", total) if total > 0 { printQueryInfo(res, err) } else { fmt.Println("Not found!") }}// 打印查问到的输入func printQueryInfo(res *elastic.SearchResult, err error) { if err != nil { print(err.Error()) return } // 通过Each办法,将es后果的json构造转换成struct对象 for _, item := range res.Each(reflect.TypeOf(queryInfo)) { //从搜寻后果中取数据的办法 if q, ok := item.(QueryInfo); ok { fmt.Printf("%#v\n", q) } }}func main() { Search()}
官网库go-elasticsearch应用:
package mainimport ( "bytes" "encoding/json" "fmt" "github.com/elastic/go-elasticsearch/v7" "log")func main() { cfg := elasticsearch.Config{ Addresses: []string{ "http://sgp.api.es.che", }, Username: "anzhihe", Password: "anzhihe", } var buf bytes.Buffer query := map[string]interface{}{ "query": map[string]interface{}{ "match": map[string]interface{}{ "domain": "api.pay.chegva.com", }, }, } if err := json.NewEncoder(&buf).Encode(query); err != nil { log.Fatalf("Error encoding query: %s", err) } es, _ := elasticsearch.NewClient(cfg) log.Println(es.Info()) result, err := es.Search(es.Search.WithIndex("chegva_ngx_proxy_log"), es.Search.WithBody(&buf)) if err != nil { fmt.Println(err) } fmt.Println(result)}
除上述应用计划,还能够应用 Http申请接口:
func query(url string,username string,password string) { jsonData := `{"query": {"term": {"request.data.id": "953c142cac566635120578a"}}}` req, _ := http.NewRequest("POST", url, strings.NewReader(jsonData)) req.Header.Add("Content-Type", "application/json") req.SetBasicAuth(username, password) res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) fmt.Println(string(body))}
term多条件查问
{ "query": { "bool": { "filter": [ { "match_phrase": { "appid": "network" } }, { "match_phrase": { "requestid": "bbf60d576b6a08a8c3c1f2cd9" } } ] } }}
参考文章:
https://blog.csdn.net/qq_3785...
https://www.tizi365.com/archi...
https://blog.csdn.net/leo_jk/...