mailru/easyjson
库的特点就是咱们只须要提供构造体,而后用这些构造体生成编码解码的代码。
示例的我的项目名为elasticsearch/encoding/json
。
一、创立 models
在我的项目中新建 model 目录,目录中新建两个文件model.go
和response.go
,在这两个文件头都增加一行代码生成正文:
//go:generate easyjson -all -snake_case $GOFILE
//
后不能有空格
models.go:
//go:generate easyjson -all -snake_case $GOFILEpackage modelimport ( "time")type Article struct { ID uint Title string Body string Published time.Time Author *Author}type Author struct { FirstName string LastName string}
response.go:
//go:generate easyjson -all -snake_case $GOFILEpackage modeltype ErrorResponse struct { Info *ErrorInfo `json:"error,omitempty"`}type ErrorInfo struct { RootCause []*ErrorInfo Type string Reason string Phase string}type IndexResponse struct { Index string `json:"_index"` ID string `json:"_id"` Version int `json:"_version"` Result string}type SearchResponse struct { Took int64 Hits struct { Total struct { Value int64 } Hits []*SearchHit }}type SearchHit struct { Score float64 `json:"_score"` Index string `json:"_index"` Type string `json:"_type"` Version int64 `json:"_version,omitempty"` Source Article `json:"_source"`}
二、欠缺主逻辑代码
main.go:
package mainimport ( "bytes" "elasticsearch/encoding/json/model" "fmt" "math/rand" "os" "strconv" "strings" "time" "github.com/elastic/go-elasticsearch/v8" "github.com/elastic/go-elasticsearch/v8/esapi" "github.com/fatih/color" "github.com/mailru/easyjson")var ( out = color.New(color.Reset) faint = color.New(color.Faint) bold = color.New(color.Bold) red = color.New(color.FgRed) boldGreen = color.New(color.Bold, color.FgGreen) boldRed = color.New(color.Bold, color.FgRed) articles []model.Article fnames []string)func init() { rand.Seed(time.Now().UnixNano())}func main() { es, err := elasticsearch.NewDefaultClient() if err != nil { fmt.Printf("Error creating the client: %s\n", err) os.Exit(2) } fnames = []string{"Alice", "John", "Mary"} for i, title := range []string{"One", "Two", "Three", "Four", "Five"} { articles = append(articles, model.Article{ ID: uint(i + 1), Title: "Test" + title, Body: "Lorem ipsum dolor sit amet, consectetur adipisicing elit", Published: time.Now().AddDate(i, 0, 0), Author: &model.Author{ FirstName: fnames[rand.Intn(len(fnames))], LastName: "Smith", }, }) } faint.Println("Indexing articles...") faint.Println(strings.Repeat("━", 80)) var b bytes.Buffer for _, a := range articles { b.Reset() // 将 article 构造体序列化为 json,json 保留到 buffer 中 if _, err := easyjson.MarshalToWriter(a, &b); err != nil { red.Println("Error decoding response", err) continue } res, err := es.Index( "articles", bytes.NewReader(b.Bytes()), es.Index.WithDocumentID(strconv.Itoa(int(a.ID))), // es.Index.WithVersion(-1), // <-- 勾销此正文来触发异样 ) if err != nil { red.Printf("Error indexing article: %s\n", err) continue } defer res.Body.Close() if res.IsError() { printErrorResponse(res) os.Exit(2) } var ir model.IndexResponse if err := easyjson.UnmarshalFromReader(res.Body, &ir); err != nil { red.Println("Error decoding response", err) continue } boldGreen.Printf("[%s] ", res.Status()) fmt.Println( faint.Sprint("result=")+out.Sprint(ir.Result), faint.Sprint("index=")+out.Sprint(ir.Index), faint.Sprint("ID=")+out.Sprint(ir.ID), faint.Sprint("version=")+out.Sprint(ir.Version), ) } es.Indices.Refresh(es.Indices.Refresh.WithIndex("articles")) faint.Println("\nSearching articles...") faint.Println(strings.Repeat("━", 80)) res, err := es.Search( es.Search.WithIndex("articles"), es.Search.WithQuery("one OR two"), // es.Search.WithQuery("{{{one OR two"), // <-- 勾销此正文来触发异样 ) if err != nil { red.Printf("Error searching articles: %s\n", err) os.Exit(2) } defer res.Body.Close() if res.IsError() { printErrorResponse(res) os.Exit(2) } var sr model.SearchResponse if err := easyjson.UnmarshalFromReader(res.Body, &sr); err != nil { red.Println("Error decoding response", err) os.Exit(2) } faint.Printf("[%s] took=%d total=%d\n", res.Status(), sr.Took, sr.Hits.Total.Value) faint.Println(strings.Repeat("─", 80)) for _, h := range sr.Hits.Hits { fmt.Println( out.Sprintf("%s,", strings.Join([]string{h.Source.Author.FirstName, h.Source.Author.LastName}, " ")), bold.Sprintf("%s", h.Source.Title), out.Sprintf("(%d)", h.Source.Published.Year()), ) faint.Println(strings.Repeat("─", 80)) }}// printErrorResponse 解码 es 响应,格式化后打印到终端func printErrorResponse(res *esapi.Response) { bold.Printf("[%s] ", res.Status()) var e model.ErrorResponse if err := easyjson.UnmarshalFromReader(res.Body, &e); err != nil { red.Println("Error decoding response:", err) return } boldRed.Print(e.Info.RootCause[0].Type) faint.Print(" > ") fmt.Println(e.Info.RootCause[0].Reason)}
三、生成代码
拉取我的项目中须要的库:
go mod tidy
生成代码:
go generate ./model
之后,model 目录中会多出两个文件:model_easyjson.go
和response_easyjson.go
。
这两个文件中的代码为 model 中的构造体实现了mailru/easyjson
规定的一些接口。
四、运行我的项目
go run main.go
Indexing articles...━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[200 OK] result=updated index=articles ID=1 version=36[200 OK] result=updated index=articles ID=2 version=34[200 OK] result=updated index=articles ID=3 version=34[200 OK] result=updated index=articles ID=4 version=34[200 OK] result=updated index=articles ID=5 version=34Searching articles...━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[200 OK] took=2 total=0────────────────────────────────────────────────────────────────────────────────