Elasticearch Bulk Index Данные JSON

Я пытаюсь выполнить массовое индексирование файла JSON в новый индекс Elasticsearch и не могу этого сделать. У меня есть следующий пример данных в JSON

[{"Amount": "480", "Quantity": "2", "Id": "975463711", "Client_Store_sk": "1109"},
{"Amount": "2105", "Quantity": "2", "Id": "975463943", "Client_Store_sk": "1109"},
{"Amount": "2107", "Quantity": "3", "Id": "974920111", "Client_Store_sk": "1109"},
{"Amount": "2115", "Quantity": "2", "Id": "975463798", "Client_Store_sk": "1109"},
{"Amount": "2116", "Quantity": "1", "Id": "975463827", "Client_Store_sk": "1109"},
{"Amount": "648", "Quantity": "3", "Id": "975464139", "Client_Store_sk": "1109"},
{"Amount": "2126", "Quantity": "2", "Id": "975464805", "Client_Store_sk": "1109"},
{"Amount": "2133", "Quantity": "1", "Id": "975464061", "Client_Store_sk": "1109"},
{"Amount": "1339", "Quantity": "4", "Id": "974919458", "Client_Store_sk": "1109"},
{"Amount": "1196", "Quantity": "5", "Id": "974920538", "Client_Store_sk": "1109"},
{"Amount": "1198", "Quantity": "4", "Id": "975463638", "Client_Store_sk": "1109"},
{"Amount": "1345", "Quantity": "4", "Id": "974919522", "Client_Store_sk": "1109"},
{"Amount": "1347", "Quantity": "2", "Id": "974919563", "Client_Store_sk": "1109"},
{"Amount": "673", "Quantity": "2", "Id": "975464359", "Client_Store_sk": "1109"},
{"Amount": "2153", "Quantity": "1", "Id": "975464511", "Client_Store_sk": "1109"},
{"Amount": "3896", "Quantity": "4", "Id": "977289342", "Client_Store_sk": "1109"},
{"Amount": "3897", "Quantity": "4", "Id": "974920602", "Client_Store_sk": "1109"}]

я использую

 curl -XPOST localhost:9200/index_local/my_doc_type/_bulk --data-binary --data @/home/data1.json 

Когда я пытаюсь использовать стандартный API массового индекса из Elasticsearch, я получаю эту ошибку

 error: {"message":"ActionRequestValidationException[Validation Failed: 1: no requests added;]"}

Кто-нибудь может помочь с индексацией этого типа JSON?

Ответ 1

Что вам нужно сделать, так это прочитать этот JSON файл и затем построить массовый запрос в формате, ожидаемом _bulk конечной точкой, т.е. одна строка для команды и одна строка для документа, разделенная символом новой строки... полоскание и повторение для каждого документа:

curl -XPOST localhost:9200/your_index/_bulk -d '
{"index": {"_index": "your_index", "_type": "your_type", "_id": "975463711"}}
{"Amount": "480", "Quantity": "2", "Id": "975463711", "Client_Store_sk": "1109"}
{"index": {"_index": "your_index", "_type": "your_type", "_id": "975463943"}}
{"Amount": "2105", "Quantity": "2", "Id": "975463943", "Client_Store_sk": "1109"}
... etc for all your documents
'

Просто замените your_index и your_type на фактические имена индексов и типов, которые вы используете.

ОБНОВЛЕНИЕ

Обратите внимание, что можно сократить командную строку, удалив _index и _type, если они указаны в вашем URL-адресе. Также можно удалить _id, если вы указываете путь к вашему полю id в своем сопоставлении (обратите внимание, что эта функция будет устаревать в ES 2.0). По крайней мере, ваша командная строка может выглядеть как {"index":{}} для всех документов, но она всегда будет обязательной, чтобы указать, какую операцию вы хотите выполнить (в данном случае index документ)

ОБНОВЛЕНИЕ 2

curl -XPOST localhost:9200/index_local/my_doc_type/_bulk --data-binary  @/home/data1.json

/home/data1.json должен выглядеть следующим образом:

{"index":{}}
{"Amount": "480", "Quantity": "2", "Id": "975463711", "Client_Store_sk": "1109"}
{"index":{}}
{"Amount": "2105", "Quantity": "2", "Id": "975463943", "Client_Store_sk": "1109"}
{"index":{}}
{"Amount": "2107", "Quantity": "3", "Id": "974920111", "Client_Store_sk": "1109"}

Ответ 2

На сегодняшний день, 6.1.2 - это последняя версия ElasticSearch, а команда curl, которая работает для меня в Windows (x64),

curl -s -XPOST localhost:9200/my_index/my_index_type/_bulk -H "Content-Type: 
application/x-ndjson" --data-binary @D:\data\mydata.json

Формат данных, которые должны присутствовать в mydata.json, остается таким же, как показано в ответе @val

Ответ 3

Действительный массовый API- запрос Elasticsearch будет выглядеть примерно так (оканчивается новой строкой):

POST http://localhost: 9200/products_slo_development_temp_2/productModel/_bulk

{ "index":{ } } 
{"RequestedCountry":"slo","Id":1860,"Title":"Stol"} 
{ "index":{ } } 
{"RequestedCountry":"slo","Id":1860,"Title":"Miza"} 

Документация по API для Elasticsearch: https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html

Вот как я это делаю

Я посылаю запрос HTTP POST, с uri valiable как URI/URL запроса HTTP и elasticsearchJson переменной в JSON, переданную в теле запроса HTTP, отформатированный для объемного апи Elasticsearch:

var uri = @"/" + indexName + "/productModel/_bulk";
var json = JsonConvert.SerializeObject(sqlResult);
var elasticsearchJson = GetElasticsearchBulkJsonFromJson(json, "RequestedCountry");

Вспомогательный метод для генерации необходимого формата json для массового API Elasticsearch:

public string GetElasticsearchBulkJsonFromJson(string jsonStringWithArrayOfObjects, string firstParameterNameOfObjectInJsonStringArrayOfObjects)
{
  return @"{ ""index"":{ } } 
" + jsonStringWithArrayOfObjects.Substring(1, jsonStringWithArrayOfObjects.Length - 2).Replace(@",{""" + firstParameterNameOfObjectInJsonStringArrayOfObjects + @"""", @" 
{ ""index"":{ } } 
{""" + firstParameterNameOfObjectInJsonStringArrayOfObjects + @"""") + @"
";
}

Первое свойство/поле в моем объекте JSON - это свойство RequestedCountry, поэтому я использую его в этом примере.

productModel - это мой тип документа productModel. sqlResult - это общий список С# с продуктами.