【问题标题】:Unable to insert a record into ElasticSearch using node.js http.request - MapperParsingException[failed to parse]无法使用 node.js http.request 将记录插入 ElasticSearch - MapperParsingException [无法解析]
【发布时间】:2015-08-31 02:29:30
【问题描述】:

尝试使用 node.js 的 http 模块将记录插入 ElasticSearch( 使用 3rd 方模块)

设置:在端口 9200 上本地运行 ElasticSearch 实例(默认)

Node.js 代码:

var querystring = require('querystring'); // to build our post string
var http = require('http');

// Build the post string from an object
var data = querystring.stringify({
  "text" :"hello world"
});

// An object of options to indicate where to post to
var post_options = {
    host: 'localhost',
    port: '9200',
    path: '/twitter/tweets/1',
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(data)
    }
};

// Set up the request
var post_req = http.request(post_options, function(res) {
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
        console.log('Response: ' + chunk);
    });
});

// post the data
post_req.write(data);
post_req.end();

我收到以下错误

{"error":"MapperParsingException[failed to parse]; nested: 
ElasticsearchParseException[Failed to derive xcontent 
from (offset=0, length=18): [116, 101, 120, 116, 61, 104, 
101, 108, 108, 111, 37, 50, 48, 119, 111, 114, 108, 100]]; ",
"status":400}

但是执行以下 CURL 可以按预期工作:

curl -XPOST 'http://localhost:9200/twitter/tweet/1' -d '{"message" : "hello world"}'

我查看了以下具有类似错误消息的 StackOverflow 问题:

这些都没有回答我的问题。

任何帮助非常感谢。 谢谢

注意:我故意尝试使用仅使用 Node.js Core 的 ElasticSearch REST API( 没有第 3 方)模块(请不要建议使用 elasticsearch-jsesrequest 等)

【问题讨论】:

    标签: javascript node.js rest http elasticsearch


    【解决方案1】:

    回想起来很明显
    使用 querystring 模块是错误的。
    ElasticSearch 期望数据以 JSON(“字符串化”)形式发送

    所以代码必须是:

    var http = require('http');
    
    // ElasticSearch Expects JSON not Querystring!
    var data = JSON.stringify({
      "text" :"everything is awesome"
    });
    
    // An object of options to indicate where to post to
    var post_options = {
        host: 'localhost',
        port: '9200',
        path: '/twitter/tweets/1234',
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Content-Length': Buffer.byteLength(data)
        }
    };
    
    // Set up the request
    var post_req = http.request(post_options, function(res) {
        res.setEncoding('utf8');
        res.on('data', function (chunk) {
            console.log('Response: ' + chunk);
        });
    });
    
    // post the data
    post_req.write(data);
    post_req.end();
    

    按预期工作。确认使用:

    curl -GET http://localhost:9200/twitter/tweets/1234?pretty
    

    感谢 @FelipeAlmeida 帮助我实现这一点)

    【讨论】:

    • 对于任何阅读本文的人来说,最后的 curl 示例都缺少作为 URL 一部分的 'tweet' 末尾的 's'
    • 谢谢@jtromans 我已经修正了错字。觉得它对你有用。
    【解决方案2】:

    虽然可以使用 formencoding 对 Elasticsearch 上的数据进行索引(我不确定,我得研究一下),但 99% 与 Elasticsearch 交谈的方式是通过纯 JSON 请求。

    所以尝试将'Content-Type': 'application/x-www-form-urlencoded' 更改为'Content-type': 'application/json' 并告诉我它是否有效。

    【讨论】:

    • 我应该在发布这个问题之前给出我尝试过的事情的完整列表。将 Content-Type 更改为 'application/json' 就是其中之一。可悲的是它没有解决它。 :-(
    • 将内容类型更改为 application/json 是成功的一半。最重要的部分是以 JSON 格式发送数据......我正在对数据进行 url 编码而不是执行 JSON.stringify() - 感谢您为我指明正确的方向。
    • 好的。很高兴能提供帮助 =)
    猜你喜欢
    • 1970-01-01
    • 2018-11-03
    • 2014-09-03
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-04
    • 2020-01-11
    相关资源
    最近更新 更多