2014-05-22 48 views
25

Elasticsearch批量導入。JSON批量導入Elasticstearch

我需要導入產品作爲單個項目。

我有一個JSON文件看起來類似於以下內容:

{ 
    "Products":[ 
     { 
     "Title":"Product 1", 
     "Description":"Product 1 Description", 
     "Size":"Small", 
     "Location":[ 
      { 
       "url":"website.com", 
       "price":"9.99", 
       "anchor":"Prodcut 1" 
      } 
     ], 
     "Images":[ 
      { 
       "url":"product1.jpg" 
      } 
     ], 
     "Slug":"prodcut1" 
     }, 
     { 
     "Title":"Product 2", 
     "Description":"Prodcut 2 Desctiption", 
     "Size":"large", 
     "Location":[ 
      { 
       "url":"website2.com", 
       "price":"99.94", 
       "anchor":"Product 2" 
      }, 
      { 
       "url":"website3.com", 
       "price":"79.95", 
       "anchor":"discount product 2" 
      } 
     ], 
     "Images":[ 
      { 
       "url":"image.jpg" 
      }, 
      { 
       "url":"image2.jpg" 
      } 
     ], 
     "Slug":"product2" 
     } 
    ] 
} 

下面我試過(我在這個新手):

curl -s -XPOST 'http://localhost:9200/_bulk' --data-binary @products.json 
curl -s -XPOST 'http://localhost:9200/_bulk' -d @products.json 
curl -XPOST http://localhost:9200/cp/products -d "@products.json" 
curl -XPOST http://localhost:9200/products -d "@products.json" 

了一些錯誤其他人沒有。我需要做什麼?

+0

HTTPS://discuss.elastic。 co/t/postgres-streams-to-elastic-streams/92798 任何指針在這一個! –

回答

22

Bulk API documentation。您需要提供批量操作,格式非常明確:

注意:最後一行數據必須以換行符結尾\ n。

可能的操作是索引,創建,刪除和更新。索引並創建期望下一行的源代碼,並且具有與標準索引API的op_type參數相同的語義(即,如果已經存在具有相同索引和類型的文檔,則創建將失敗,而索引將添加或替換文檔有必要的)。刪除不期望下列行中的源,並且具有與標準刪除API相同的語義。 update期望在下一行指定部分doc,upsert和腳本及其選項。

如果您提供的文本文件輸入爲curl,則必須使用--data-binary標誌而不是plain -d。後者不保留換行符。

所以,你需要將你products.json文件的內容更改爲以下:

{"index":{"_index":"cp", "_type":"products", "_id": "1"}} 
{ "Title":"Product 1", "Description":"Product 1 Description", "Size":"Small", "Location":[{"url":"website.com", "price":"9.99", "anchor":"Prodcut 1"}],"Images":[{ "url":"product1.jpg"}],"Slug":"prodcut1"} 
{"index":{"_index":"cp", "_type":"products", "_id":"2"}} 
{"Title":"Product 2", "Description":"Prodcut 2 Desctiption", "Size":"large","Location":[{"url":"website2.com", "price":"99.94","anchor":"Product 2"},{"url":"website3.com","price":"79.95","anchor":"discount product 2"}],"Images":[{"url":"image.jpg"},{"url":"image2.jpg"}],"Slug":"product2"} 

而且一定要在你的curl命令使用--data-binary(如您的第一個命令)。另請注意,如果您使用索引並鍵入特定端點,則可以省略indextype。你的第三個捲曲命令是/cp/products

+13

'_id'不是必需的。如果省略,Elasticsearch將自動生成一個。 – llernestal

+4

另外值得注意的是:端點是'/ _bulk','/ {index}/_ bulk'和'{index}/{type}/_ bulk'。當提供'index'或'index/type'時,默認情況下,它們將在未明確提供的批量項目中使用。 –

+0

https://discuss.elastic.co/t/postgres-streams-to-elastic-streams/92798 在這一個任何指針! –

3

我最終寫了一個「完全沒有優化」的bash腳本來爲我做這件事。數據集相對較小,因此這可以滿足我的需求。

#!/bin/bash 
COUNTER=0 
CURLURL="http://127.0.0.1:9200/cp/products" 
COUNT=$(less products.json | jq '.Products | length')  
while [ $COUNTER -lt $COUNT ]; do 
    echo $COUNTER 
    CURLDATA=$(less products.json | jq '.Products['$COUNTER']') 
    RESPONSE=$(curl -XPOST "$CURLURL" -d "$CURLDATA" -vn) 
    let COUNTER=COUNTER+1 
done 
+0

如果您收到「jq:command not found」錯誤,您可以從這裏安裝jq:https://stedolan.github.io/jq/download/(最有可能) –

2

我可以用下面的腳本sed添加必要的標頭:

sed -e 's/^/{ "index" : {} }\n/' -i products.json 

這將增加該文件中的每一行以上的空指數。只要在URL中指定了索引和類型,就允許使用空索引。之後,正確的電話將是

curl -s -XPOST http://localhost:9200/cp/products/_bulk --data-binary @products.json 
2

這是快速和工作對我的JSON對象數組。

cat data.json | \ 
jq -c '.[] | .id = ._id | del (._id) | {"index": {"_index": "profiles", "_type": "gps", "_id": .id}}, .' |\ 
curl -XPOST 127.0.0.1:9200/_bulk --data-binary @- 

我不得不做的副本和_id場的刪除作爲導入扔一個錯誤(領域_id]是一個元數據字段,並且不能在文檔內加入。使用索引API請求參數。)如果它沒有被重命名。大多數數據不可能有_id字段,在這種情況下應該省略這部分。

信用爲這Kevin Marsh

+0

謝謝。這工作就像一個魅力!我使用原始解決方案'cat file.json | jq -c'。[] | {「index」:{「_index」:「書籤」,「_type」:「書籤」,「_id」:.id}},'' | curl -XPOST localhost:9200/_bulk --data-binary @ -' –

1

另一種選擇是使用json-to-es-bulk工具。

運行以下到您的JSON文件轉換爲NDJSON:

node ./index.js -f file.json --index index_name --type type_name 

這將創建request-data.txt文件,它可以散裝進口:

curl -H "Content-Type: application/json" -XPOST "http://localhost:9200/my_index/my_type/_bulk?pretty" --data-binary "@request-data.txt"