node.js - AWS Elasticsearch http请求,错误 'The bulk request must be terminated by a newline'

标签 node.js amazon-web-services elasticsearch https bulk

我已经使用this link使用JSON.stringified(body)创建了一个批量http请求,如下所示:

const body = [ { index: { _index: 'image_2', _type: '_doc', _id: 0 } },
{ imageKey: 'test' },
{ index: { _index: 'image_2', _type: '_doc', _id: 1 } },
{ imageKey: 'test2' } ]

但我不断收到错误
{ statusCode: 400,
body: '{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"The bulk request must be terminated by a newline [\\\\n]"}],"type":"illegal_argument_exception","reason":"The bulk request must be terminated by a newline [\\\\n]"},"status":400}' }

我已经在下面尝试过了,但是它也不起作用:
const body = `${JSON.stringified(body)\n}`;

任何想法表示赞赏:)

这是我的aws elastic search function:
function elasticsearchFetch(elasticsearchDomain, endpointPath, options = {}, region = process.env.AWS_REGION) {
  return new Promise((resolve, reject) => {
    const { body, method = 'GET' } = options;

    const endpoint = new AWS.Endpoint(elasticsearchDomain);
    const request = new AWS.HttpRequest(endpoint, region);
    request.method = method;
    request.path += endpointPath;
    request.headers.host = elasticsearchDomain;
    if (body) {
      request.body = body;
      request.headers['Content-Type'] = 'application/json';
      request.headers['Content-Length'] = request.body.length;
    }

    const credentials = new AWS.EnvironmentCredentials('AWS');
    const signer = new AWS.Signers.V4(request, 'es');
    signer.addAuthorization(credentials, new Date());

    const client = new AWS.HttpClient();
    client.handleRequest(request, null, (res) => {
      res.on('data', (chunk) => {
        chunks += chunk;
      });
      res.on('end', () => resolve({ statusCode: res.statusCode, body: chunks }));
    }, error => reject(error));
  });
}

这是使用上述请求签名者的lambda函数的代码:
const elasticsearchFetch = require('rms-library/fetch');
exports.handler = async ({ imageID, bulk, products }) => {
  if (!Array.isArray(products) || !imageID) {
    throw new Error('error in bulk operation');
  }
  const bulkList = [];
  products.forEach((product, i) => {
    bulkList.push({ index: { _index: imageID, _type: '_doc', _id: i } });
    bulkList.push(product);
  });
  bulkList.push('');
  console.log('bulkList', bulkList);
  const result = await elasticsearchFetch.elasticsearch(
    process.env.ELASTIC_SEARCH_DOMAIN,
    '_bulk',
    { method: 'PUT', body: JSON.stringify(bulkList) },
  );
  console.log(result);
};

最佳答案

好的,首先,您需要使用POST代替PUT端点的_bulk,并且主体不能是字符串化的JSON数组。

尝试像这样:

const result = await elasticsearchFetch.elasticsearch(
  process.env.ELASTIC_SEARCH_DOMAIN,
  '_bulk',
  { method: 'POST', body: bulkList.map(json => {return JSON.stringify(json);}).join('\n') + '\n' },
);

关于node.js - AWS Elasticsearch http请求,错误 'The bulk request must be terminated by a newline',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57987172/

相关文章:

javascript - bcrypt.compare 是否容易受到定时攻击

java - 如何使用 java aws sdk 创建 aws ec2 时提供实例的名称

unix - 终止由 `node . >/dev/null 2>/dev/null </dev/null &` 创建的在端口 3000 上运行的重生服务器

elasticsearch - 将 "repository-s3"插件用于 ElasticSearch 时出错

elasticsearch - 在 Elasticsearch 中的 multi_match 查询中获取分数分割

node.js - 我们如何检测我们的脚本是通过命令行还是通过浏览器启动?

javascript - Node.js 相当于 Yarn 命令

javascript - ('eventName' , function(){...}); 上的这个模式 : . 的名称是什么?

json - "Encountered unsupported property Type"Route53 的 Cloudformation 错误

php - 替换默认的Elasticsearch分数