2016-04-21 14 views
14

Ho un file JSON e ho bisogno di indicizzarlo sul server ElasticSearch.Convalida non riuscita: 1: nessuna richiesta aggiunta all'indicizzazione di massa ElasticSearch

file di JSOIN assomiglia a questo:

{ 
    "sku": "1", 
    "vbid": "1", 
    "created": "Sun, 05 Oct 2014 03:35:58 +0000", 
    "updated": "Sun, 06 Mar 2016 12:44:48 +0000", 
    "type": "Single", 
    "downloadable-duration": "perpetual", 
    "online-duration": "365 days", 
    "book-format": "ePub", 
    "build-status": "In Inventory", 
    "description": "On 7 August 1914, a week before the Battle of Tannenburg and two weeks before the Battle of the Marne, the French army attacked the Germans at Mulhouse in Alsace. Their objective was to recapture territory which had been lost after the Franco-Prussian War of 1870-71, which made it a matter of pride for the French. However, after initial success in capturing Mulhouse, the Germans were able to reinforce more quickly, and drove them back within three days. After forty-three years of peace, this was the first test of strength between France and Germany. In 1929 Karl Deuringer wrote the official history of the battle for the Bavarian Army, an immensely detailed work of 890 pages; First World War expert and former army officer Terence Zuber has translated this study and edited it down to more accessible length, to produce the first account in English of the first major battle of the First World War.", 
    "publication-date": "07/2014", 
    "author": "Deuringer, Karl", 
    "title": "The First Battle of the First World War: Alsace-Lorraine", 
    "sort-title": "First Battle of the First World War: Alsace-Lorraine", 
    "edition": "0", 
    "sampleable": "false", 
    "page-count": "0", 
    "print-drm-text": "This title will only allow printing of 2 consecutive pages at a time.", 
    "copy-drm-text": "This title will only allow copying of 2 consecutive pages at a time.", 
    "kind": "book", 
    "fro": "false", 
    "distributable": "true", 
    "subjects": { 
     "subject": [ 
     { 
      "-schema": "bisac", 
      "-code": "HIS027090", 
      "#text": "World War I" 
     }, 
     { 
      "-schema": "coursesmart", 
      "-code": "cs.soc_sci.hist.milit_hist", 
      "#text": "Social Sciences -> History -> Military History" 
     } 
     ] 
    }, 
    "pricelist": { 
     "publisher-list-price": "0.0", 
     "digital-list-price": "7.28" 
    }, 
    "publisher": { 
     "publisher-name": "The History Press", 
     "imprint-name": "The History Press Ireland" 
    }, 
    "aliases": { 
     "eisbn-canonical": "1", 
     "isbn-canonical": "1", 
     "print-isbn-canonical": "9780752460864", 
     "isbn13": "1", 
     "isbn10": "0750951796", 
     "additional-isbns": { 
     "isbn": [ 
      { 
      "-type": "print-isbn-10", 
      "#text": "0752460862" 
      }, 
      { 
      "-type": "print-isbn-13", 
      "#text": "97807524608" 
      } 
     ] 
     } 
    }, 
    "owner": { 
     "company": { 
     "id": "1893", 
     "name": "The History Press" 
     } 
    }, 
    "distributor": { 
     "company": { 
     "id": "3658", 
     "name": "asc" 
     } 
    } 
    } 

Ma quando cerco di indicizzazione questo file JSON utilizzando il comando

curl -XPOST 'http://localhost:9200/_bulk' -d @1.json 

ottengo questo errore:

{"error":{"root_cause":[{"type":"action_request_validation_exception","reason":"Validation Failed: 1: no requests added;"}],"type":"action_request_validation_exception","reason":"Validation Failed: 1: no requests added;"},"status":400} 

I don' so dove sto sbagliando.

risposta

23

L'API bulk di Elasticsearch utilizza una sintassi speciale, che in realtà è composta da documenti json scritti su linee singole. Dai uno sguardo allo documentation.

La sintassi è piuttosto semplice. Per l'indicizzazione, la creazione e l'aggiornamento sono necessari 2 documenti JSON a riga singola. Le prime righe indicano l'azione, la seconda dà il documento all'indice/crea/aggiorna. Per cancellare un documento, è necessaria solo la linea di azione. Per esempio (dalla documentazione):

{ "index" : { "_index" : "test", "_type" : "type1", "_id" : "1" } } 
{ "field1" : "value1" } 
{ "create" : { "_index" : "test", "_type" : "type1", "_id" : "3" } } 
{ "field1" : "value3" } 
{ "update" : {"_id" : "1", "_type" : "type1", "_index" : "index1"} } 
{ "doc" : {"field2" : "value2"} } 
{ "delete" : { "_index" : "test", "_type" : "type1", "_id" : "2" } } 

Non dimenticare di terminare il file con una nuova linea. Poi, per chiamare l'API di massa utilizzare il comando:

curl -s -XPOST localhost:9200/_bulk --data-binary "@requests" 

Dalla documentazione:

If you’re providing text file input to curl, you must use the --data-binary flag instead of plain -d

+1

"Non dimenticare di terminare il file con una nuova riga." Grazie! Mi ha salvato un'ora qui. –

+6

** Non dimenticare di terminare il tuo file con una nuova riga ** .. 3 al mattino imprecando contro il portatile, mi hai appena salvato la vita .. –

+0

Inoltre, cosa stupida da fare ... non che io lo farei ... la documentazione dice "@requests" '--data-binari' Il '@' deve essere prima il nome del file, se, lo dimentichi, fallisce pure. –

0

ho avuto un problema simile in che volevo eliminare un documento specifico di un tipo specifico e tramite la risposta di cui sopra sono riuscito a far funzionare finalmente il mio semplice script di bash!

Ho un file che ha un document_id per riga (document_id.txt) e che utilizza il seguente script bash. Posso cancellare i documenti di un certo tipo con il documento id indicato.

Questo è ciò che il file si presenta come:

c476ce18803d7ed3708f6340fdfa34525b20ee90 
5131a30a6316f221fe420d2d3c0017a76643bccd 
08ebca52025ad1c81581a018febbe57b1e3ca3cd 
496ff829c736aa311e2e749cec0df49b5a37f796 
87c4101cb10d3404028f83af1ce470a58744b75c 
37f0daf7be27cf081e491dd445558719e4dedba1 

Lo script bash si presenta così:

#!/bin/bash 

es_cluster="http://localhost:9200" 
index="some-index" 
doc_type="some-document-type" 

for doc_id in `cat document_id.txt` 
do 
    request_string="{\"delete\" : { \"_type\" : \"${doc_type}\", \"_id\" : \"${doc_id}\" } }" 
    echo -e "${request_string}\r\n\r\n" | curl -s -XPOST "${es_cluster}/${index}/${doc_type}/_bulk" --data-binary @- 
    echo 
done 

Il trucco, dopo un sacco di frustrazione, è stato quello di utilizzare l'opzione -e per echo e aggiungere \ n \ n all'output di echo prima che lo si condensasse in arricciatura.

E poi nel ricciolo ho quindi la possibilità --data-binary impostato per fermarlo escludendo l'\ n \ n necessario per l'endpoint _bulk seguito dal @ - opzione per ottenere leggere da stdin!

Problemi correlati