JSON批量导入Elasticstearch

时间:2014-05-22 05:26:45

标签: elasticsearch

Elasticsearch批量导入。

我需要将产品作为单个项目导入。

我有一个类似于以下内容的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"

有些人给出了其他人没有的错误。我需要做什么?

5 个答案:

答案 0 :(得分:27)

关注Bulk API documentation。您需要使用非常具体格式的文件提供批量操作:

  

注意:最后一行数据必须以换行符结尾\ n。

     

可能的操作是索引,创建,删除和更新。 index和create期望下一行的源,并且具有与标准索引API的op_type参数相同的语义(即,如果已经存在具有相同索引和类型的文档,则create将失败,而index将添加或替换文档有必要的)。 delete不期望下一行中的源,并且具有与标准删除API相同的语义。 update期望在下一行指定部分doc,upsert和script及其选项。

     

如果要为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就像你的第三个卷曲命令一样。

答案 1 :(得分:3)

我最终编写了一个bash脚本,而且#34;根本没有优化"为我这样做。数据集相对较小,因此可以满足我的需求。

#!/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

答案 2 :(得分:3)

这对我来说很快就适用于一系列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字段,因为导入引发了错误( Field [_id]是元数据字段,无法在文档中添加。使用索引API请求参数。)如果没有重命名。大多数数据不太可能有_id字段,在这种情况下应省略此部分。

归功于Kevin Marsh

答案 3 :(得分:2)

我能够使用以下sed脚本添加必要的标头:

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

这将在文件的每一行上方添加一个空索引。只要在URL中指定了索引和类型,就允许空索引。在那之后,正确的呼叫将是

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

答案 4 :(得分:2)

另一种选择是使用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"