golang解析csv並匯入elastic search

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

今天我們一起來寫一個從csv檔案將資料匯入elastic search的小程式

準備工作

在gopath的src檔案夾下建立csv2es檔案夾,並建立main.go檔案。下載一些csv檔案備用

解析命令列參數

首先我們需要使用flag package解析命令列參數,代碼如下

func main() {  // 解析命令列輸入  host := flag.String("host", "http://localhost:9200", "host, e.g. http://localhost:9200")  file := flag.String("file", "", "file path")  esIndex := flag.String("index", "", "elastic search index")  esType := flag.String("type", "", "elastic search type")  flag.Parse()  if *file == "" {    fmt.Println("please set which csv file you want to import clearly")    return  }  if *esIndex == "" {    fmt.Println("please set elastic search index")    return  }  if *esType == "" {    fmt.Println("please set elastic search type")    return  }...}

主要解析的參數有es的地址,待匯入的檔案的路徑,匯入到的es的index和type。運行go build,產生可執行檔csv2go,執行

csv2go -h-file string        file path (default "")  -host string        host, e.g. http://localhost:9200 (default "http://localhost:9200")  -index string        elastic search index (default "")  -type string        elastic search type (default "")

串連es

elastic這個開源項目可以協助我們串連elastic

  // 串連es  ctx := context.Background()  client, err := elastic.NewClient(    elastic.SetURL(*host),    elastic.SetSniff(false))  if err != nil {    panic(err)  }  // 檢查index是否存在,如果不存在則建立index  exists, err := client.IndexExists(*esIndex).Do(ctx)  if err != nil {    panic(err)  }  if !exists {    createIndex, err := client.CreateIndex(*esIndex).Do(ctx)    if err != nil {      panic(err)    }  }

解析csv並匯入(index)到elastic search

這裡需要注意幾點。第一,Mac上會存在\r結尾的檔案的問題,所以我們使用macreader這個包對io.Reader包了一層,有興趣的同學可以看我之前的文章《mac上的檔案有毒》,第二,我們預設csv檔案的第一行為column name,後面各行都是合法的記錄。

  // 解析csv  f, _ := os.Open(*file)  r := csv.NewReader(macreader.New(bufio.NewReader(f)))  keys, err := r.Read()  for {                                            //1    record, err := r.Read()    if err == io.EOF {      break    }    m := make(map[string]string)    for i, key := range keys {      m[key] = record[i]    }    jsonStr, err := json.Marshal(m)    if err != nil {      panic(err)    }    put1, err := client.Index().            Index(*esIndex).            Type(*esType).            BodyString(string(jsonStr)).            Do(ctx)    if err != nil {      // Handle error      panic(err)    }    fmt.Printf("Indexed tweet %s to index %s, type %s\n", put1.Id, put1.Index, put1.Type)  }                                           //2

ok,一個基本的將csv中的資料匯入elastic search的程式完成了,我們來測試一下效能吧。在上面的(1)行代碼前面加上

start := time.Now().Unix()

在上面的(2)行代碼後面加上

end := time.Now().Unix()fmt.Println(end, start)

測試了一下跑了一個61567條記錄的檔案,一共跑了36分鐘。夠我睡一個午覺了...

提升效率

elastic search有一個bulk api,可以將一些操作合并起來,同時傳遞給elastic search處理並返回

  // 建立一個Bulk  bulkRequest := client.Bulk()  for {    ...    // 為每一條記錄產生一個IndexRequest並加入Bulk    req := elastic.NewBulkIndexRequest().Index(*esIndex).Type(*esType).Doc(string(jsonStr))    bulkRequest.Add(req)  }  // 一次性完成請求  bulkResponse, err := bulkRequest.Do(ctx)  if err != nil {  }  indexed := bulkResponse.Indexed()  fmt.Println("向es匯入了",len(indexed),"條資料")

最佳化過後,插入相同的6萬多條記錄只需要幾秒鐘。cool ^_^

本文的代碼已經開源在github,歡迎使用或者提出意見。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.