go-common/app/job/main/search/dao/es.go

244 lines
6.3 KiB
Go
Raw Normal View History

2019-04-22 10:49:16 +00:00
package dao
import (
"context"
"fmt"
"reflect"
"strconv"
"time"
"go-common/app/job/main/search/model"
"go-common/library/log"
"go-common/library/stat/prom"
"gopkg.in/olivere/elastic.v5"
)
// BulkDatabusData 写入es数据来自databus.
func (d *Dao) BulkDatabusData(c context.Context, attrs *model.Attrs, writeEntityIndex bool, bulkData ...model.MapData) (err error) {
// TODO 需要兼容
var (
request elastic.BulkableRequest
bulkRequest = d.ESPool[attrs.ESName].Bulk()
//indexField = ""
)
//s := strings.Split(attrs.DataSQL.DataIndexSuffix, ";")
//if len(s) >= 2 {
// indexField = strings.Split(s[1], ":")[0]
//}
for _, b := range bulkData {
var (
indexName string
strID string
)
if name, ok := b["index_name"]; ok {
if indexName, ok = name.(string); ok {
delete(b, "index_name")
} else {
log.Error("dao.es.BulkDBData index_name err")
continue
}
} else {
if !writeEntityIndex {
indexName, _ = b.Index(attrs)
} else {
_, indexName = b.Index(attrs)
}
}
if id, ok := b["index_id"]; ok {
if strID, ok = id.(string); !ok {
log.Error("es.BulkDBData.strID(%v)", id)
continue
}
} else {
if strID, ok = b.StrID(attrs); !ok {
log.Error("es.BulkDBData.strID")
continue
}
}
if indexName == "" {
continue
}
for _, v := range attrs.DataSQL.DataIndexRemoveFields {
delete(b, v)
}
if _, ok := b["index_field"]; ok {
delete(b, "index_field")
//delete(b, indexField)
delete(b, "ctime")
delete(b, "mtime")
}
for k := range b {
if !d.Contain(k, attrs.DataSQL.DataIndexFormatFields) {
delete(b, k)
}
}
key := []string{}
for k := range b {
key = append(key, k)
}
for _, k := range key {
customType, ok := attrs.DataSQL.DataIndexFormatFields[k]
if ok {
switch customType {
case "ip":
switch b[k].(type) {
case float64:
ipFormat := b.InetNtoA(int64(b[k].(float64)))
b[k+"_format"] = ipFormat
case int64:
ipFormat := b.InetNtoA(b[k].(int64))
b[k+"_format"] = ipFormat
}
case "arr":
var arr []int
binaryAttributes := strconv.FormatInt(b[k].(int64), 2)
for i := len(binaryAttributes) - 1; i >= 0; i-- {
b := fmt.Sprintf("%c", binaryAttributes[i])
if b == "1" {
arr = append(arr, len(binaryAttributes)-i)
}
}
b[k+"_format"] = arr
case "bin":
var arr []int
binaryAttributes := strconv.FormatInt(b[k].(int64), 2)
for i := len(binaryAttributes) - 1; i >= 0; i-- {
b := fmt.Sprintf("%c", binaryAttributes[i])
if b == "1" {
arr = append(arr, len(binaryAttributes)-i)
}
}
b[k] = arr
case "workflow":
if state, ok := b[k].(int64); ok {
b["state"] = state & 15
b["business_state"] = state >> 4 & 15
delete(b, k)
}
case "time":
if v, ok := b[k].(string); ok {
if v == "0000-00-00 00:00:00" {
b[k] = "0001-01-01 00:00:00"
}
}
default:
// as long as you happy
}
}
}
if strID == "" {
request = elastic.NewBulkIndexRequest().Index(indexName).Type(attrs.Index.IndexType).Doc(b)
} else {
request = elastic.NewBulkUpdateRequest().Index(indexName).Type(attrs.Index.IndexType).Id(strID).Doc(b).DocAsUpsert(true)
}
//fmt.Println(request)
bulkRequest.Add(request)
}
if bulkRequest.NumberOfActions() == 0 {
return
}
now := time.Now()
// prom.BusinessInfoCount.Add("redis:bulk:doc", int64(bulkRequest.NumberOfActions()))
for i := 0; i < bulkRequest.NumberOfActions(); i++ {
prom.BusinessInfoCount.Incr("redis:bulk:doc")
}
if _, err = bulkRequest.Do(c); err != nil {
log.Error("appid(%s) bulk error(%v)", attrs.AppID, err)
}
prom.LibClient.Timing("redis:bulk", int64(time.Since(now)/time.Millisecond))
return
}
// BulkDBData 写入es数据来自db.
func (d *Dao) BulkDBData(c context.Context, attrs *model.Attrs, writeEntityIndex bool, bulkData ...model.MapData) (err error) {
var (
indexName string
strID string
request elastic.BulkableRequest
bulkRequest = d.ESPool[attrs.ESName].Bulk()
)
for _, b := range bulkData {
if name, ok := b["index_name"]; ok {
if indexName, ok = name.(string); ok {
delete(b, "index_name")
} else {
log.Error("dao.es.BulkDBData index_name err")
continue
}
} else {
if !writeEntityIndex {
indexName, _ = b.Index(attrs)
} else {
_, indexName = b.Index(attrs)
}
}
if id, ok := b["index_id"]; ok {
if strID, ok = id.(string); !ok {
log.Error("es.BulkDBData.strID(%v)", id)
continue
}
} else {
if strID, ok = b.StrID(attrs); !ok {
log.Error("es.BulkDBData.strID")
continue
}
}
if indexName == "" || strID == "" {
continue
}
//attr提供要去除掉的字段不往ES中写
for _, v := range attrs.DataSQL.DataIndexRemoveFields {
delete(b, v)
}
request = elastic.NewBulkUpdateRequest().Index(indexName).Type(attrs.Index.IndexType).Id(strID).Doc(b).DocAsUpsert(true).RetryOnConflict(3)
//fmt.Println(request)
bulkRequest.Add(request)
}
if bulkRequest.NumberOfActions() == 0 {
// 注意这里request格式问题会引起action为0
return
}
log.Info("insert number is %d", bulkRequest.NumberOfActions())
now := time.Now()
// prom.BusinessInfoCount.Add("redis:bulk:doc", int64(bulkRequest.NumberOfActions()))
for i := 0; i < bulkRequest.NumberOfActions(); i++ {
prom.BusinessInfoCount.Incr("redis:bulk:doc")
}
if _, err = bulkRequest.Do(c); err != nil {
log.Error("appid(%s) bulk error(%v)", attrs.AppID, err)
}
prom.LibClient.Timing("redis:bulk", int64(time.Since(now)/time.Millisecond))
return
}
// pingEsCluster ping es cluster
func (d *Dao) pingESCluster(ctx context.Context) (err error) {
//for name, client := range d.ESPool {
// if _, _, err = client.Ping(d.c.Es[name].Addr[0]).Do(ctx); err != nil {
// d.PromError("Es:Ping", "%s:Ping error(%v)", name, err)
// return
// }
//}
return
}
// Contain .
func (d *Dao) Contain(obj interface{}, target interface{}) bool {
targetValue := reflect.ValueOf(target)
switch reflect.TypeOf(target).Kind() {
case reflect.Slice, reflect.Array:
for i := 0; i < targetValue.Len(); i++ {
if targetValue.Index(i).Interface() == obj {
return true
}
}
case reflect.Map:
if targetValue.MapIndex(reflect.ValueOf(obj)).IsValid() {
return true
}
}
return false
}