web-dev-qa-db-fra.com

Elasticearch Bulk Index JSON Data

J'essaie d'indexer en bloc un fichier JSON dans un nouvel index Elasticsearch et je ne peux pas le faire. J'ai les exemples de données suivants dans le 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"}]

J'utilise

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

Lorsque j'essaie d'utiliser l'API d'index en bloc standard d'Elasticsearch, j'obtiens cette erreur

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

Quelqu'un peut-il aider à indexer ce type de JSON?

20
Amit P

Ce que vous devez faire est de lire ce fichier JSON puis de créer une demande groupée au format attendu par le _bulk endpoint , c'est-à-dire une ligne pour la commande et une ligne pour le document, séparées par un caractère de nouvelle ligne ... rincer et répéter pour chaque document:

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
'

Assurez-vous simplement de remplacer your_index et your_type avec les noms d'index et de type réels que vous utilisez.

[~ # ~] mise à jour [~ # ~]

Notez que la ligne de commande peut être raccourcie, en supprimant _index et _type si ceux-ci sont spécifiés dans votre URL. Il est également possible de supprimer _id si vous spécifiez le chemin vers votre champ id dans votre mappage (notez que cette fonctionnalité sera déconseillée dans ES 2.0, cependant). À tout le moins, votre ligne de commande peut ressembler à {"index":{}} pour tous les documents mais il sera toujours obligatoire afin de spécifier le type d'opération que vous souhaitez effectuer (dans ce cas index le document)

MISE À JOUR 2

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

/home/data1.json devrait ressembler à ceci:

{"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"}
38
Val

À ce jour, 6.1.2 est la dernière version d'ElasticSearch, et la commande curl qui fonctionne pour moi sous Windows (x64) est

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

Le format des données qui devraient être présentes dans mydata.json reste le même que celui indiqué dans la réponse de @ val

7
Thomas

Une demande valide d'API Elasticsearch Bulk serait quelque chose comme (se terminant par une nouvelle ligne):

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"} 

Documentation de l'API Elasticsearch Bulk: https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html

Voici comment je le fais

J'envoie une POST requête http avec le uri valable comme URI/URL de la requête http et la variable elasticsearchJson est le JSON envoyé dans le corps du Demande http formatée pour l'API Elasticsearch Bulk:

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

Méthode d'aide pour générer le format json requis pour l'API Elasticsearch Bulk:

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

La première propriété/champ de mon objet JSON est la propriété RequestedCountry c'est pourquoi je l'utilise dans cet exemple.

productModel est mon type de document Elasticsearch. sqlResult est une liste générique C # avec des produits.

0
Tadej