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"
有些人给出了其他人没有的错误。我需要做什么?
答案 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
(就像你的第一个命令一样)。另请注意,如果使用索引并键入特定端点,则可以省略index
和type
。你的/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"