20

I am trying to send a JSON to elasticSearch. I have tried using Postman and SOAPUI The data is

[{"column1": "abc", "column2": "def", "column3": "dghi", "column4": "jkl", "column5": "mno"}, {"column1": "pqr", "column2": "stu", "column3": "vwx", "column4": "", "column5": ""}]

I am getting the following error back

{
  "error": {
    "root_cause": [
      {
        "type": "mapper_parsing_exception",
        "reason": "failed to parse"
      }
    ],
    "type": "mapper_parsing_exception",
    "reason": "failed to parse",
    "caused_by": {
      "type": "not_x_content_exception",
      "reason": "Compressor detection can only be called on some xcontent bytes or compressed xcontent bytes"
    }
  },
  "status": 400
}

But when I post a single JSON array I.e.

{"column1": "abc", "column2": "def", "column3": "dghi", "column4": "jkl", "column5": "mno"}

Then it works fine. I am new to ElasticSearch so not sure what is going wrong.

zessx
  • 68,042
  • 28
  • 135
  • 158
noobEngineer
  • 383
  • 1
  • 2
  • 8

9 Answers9

13

Try using curly brackets first, then naming the array. Try that and see if it works.

For example:

{root:[1, 2, 3, 4, 5]}

might work because it's contained inside an object.

Even better; while I was experimenting with JSON.stringify();, I found that it coverts arrays to JSON like so:

{1, 2, 3, 4, 5}
Jay Stevens
  • 5,863
  • 9
  • 44
  • 67
hellol11
  • 422
  • 4
  • 11
  • 24
    -1, While this is leading toward the correct answer, it's not really explanatory and the negative tone is really not helpful. The original question does have valid JSON, it's a single-element array. The issue that this question answers is that ElasticSearch requires the outermost document to be a JSON object, not a JSON array or scalar value. Example refactoring would be good too and not take too long in this case. – Samuel Neff Apr 18 '16 at 13:26
12

I recently ran into this using curl and it was a simple typo. I was not using inline json, but from a file. I forgot to include the @ sign before the filename.

curl -XPUT -H'Content-Type:application/json' localhost:9200/twitter -d@mappings.json
Brandon Kearby
  • 603
  • 7
  • 8
8

thanks @hellol11

it worked when I changed to

    {root :
[
    {"column1": "abc", "column2": "def", "column3": "dghi", "column4": "jkl", "column5": "mno"},
    {"column1": "pqr", "column2": "stu", "column3": "vwx", "column4": "", "column5": ""}

]}
noobEngineer
  • 383
  • 1
  • 2
  • 8
5

I had this issue inside a Python script (using requests) to try and POST to ES. The resolution was simply to convert the json object to a string using json.dumps()

Example (Python snipit):

import json
import requests

headers={'Content-Type': 'application/json'}
data={'hello':'barney'} 

response = requests.post('https://<my_es_domain>/<my_es_ix>/<my_doc_type>', data=json.dumps(data), headers=headers)
Scott Nestor
  • 51
  • 1
  • 1
4

In Windows environment, I solved this problem.

-d plus double quotation(") 

and surround name with backslash plus double quotaton(\")

command>

curl (more-option) -d "{\"column1\": \"abc\", \"column2\": \"def\", \"column3\": \"dghi\", \"column4\": \"jkl\", \"column5\": \"mno\"}"
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
Jung
  • 66
  • 3
1

I was getting the same error while trying to post to elasticsearch but using node js. I used the node-fetch package to make a PUT request to elasticsearch. It was weird because using the exact same thing on postman I got no error but I was getting the error on node js. I was initially doing:

const current = {
    "id" : "123456789"
}
const options = {
    method: "POST",
    headers: {
        "Content-Type": "application/json"
    },
    body: current
}

Turns out the error got fixed when I changed it to:

body: JSON.stringify(current)
raviabhiram
  • 671
  • 2
  • 8
  • 21
1

I faced similar issue when sending JSON to Elasticsearch using Python requests. This is the code snippet that caused issue. I didn't have any issue with json_docs json. It was a simple JSON object. But passing the json_docs as json param caused issue.

def dump_to_es(es_path, json_docs):
    headers = {
        'Content-Type': 'application/json',
    }   
    response = requests.put(f"http://localhost:4171/{es_path}", headers=headers, json=json_docs)
    print(f"Elasticsearch response for {es_path}:", response.text)

When passed the json_docs as data param it works without issue.

response = requests.put(f"http://localhost:4171/{es_path}", headers=headers, data=json_docs)
Bowrna
  • 61
  • 6
  • Same thing for me, your solution does indeed work. I would like to know why using the json option in requests causes this. – Andrew Grasso Dec 13 '22 at 21:44
  • 1
    check the response in this link: https://stackoverflow.com/questions/26685248/difference-between-data-and-json-parameters-in-python-requests-package/26685359#comment87016241_26685359. As mentioned by this user @michael-ekoka, that value passed on to the json parameter is double encoded. You can also check the following code in github to see where parameter passed to json passes through json.dumps (https://github.com/kennethreitz/requests/blob/083aa67a0d3309ebe37eafbe7bfd96c235a019cf/requests/models.py#L465-L471) – Bowrna Dec 19 '22 at 11:25
  • Thanks, makes perfect sense! – Andrew Grasso Dec 20 '22 at 21:41
0

In elastic search ,if you want to post bulk data then each list object must be in New line .so if you are using sense then make everything in New line or if using from code then add New line character \n...

0

For those who directly want to send data in the curl query and get the "not_x_content_exception" error, I've Managed to fix it by using double quotes:

curl -X POST "http://localhost:9200/my_index/_doc/1" -H "Content-Type: application/json" -d "{ ""name"": ""Paul"" }"