aws 弹性搜索 http 请求,错误 'The bulk request must be terminated by a newline'

aws elastic search http request , error 'The bulk request must be terminated by a newline'

我已经使用 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' },
);