节点Elasticsearch - 批量索引不起作用 - 不支持Content-Type标头[application / x-ldjson]

时间:2018-01-11 16:13:33

标签: json node.js elasticsearch

成为elasticsearch的新手,我正在通过与节点集成并尝试在Windows中执行以下在线git示例来探索它。

https://github.com/sitepoint-editors/node-elasticsearch-tutorial

在尝试从data.json导入1000个项目的数据时,执行'节点index.js'失败,出现以下错误。

通过启用跟踪,我现在将以下内容视为批量函数的根本原因。

"error": "Content-Type header [application/x-ldjson] is not supported",
** "status": 406**

我看到来自https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/changelog.html的更改日志,其中包含

  

13.0.0(2017年4月24日)发送行分隔JSON主体的批量和其他API现在使用Content-Type:application / x-ndjson标题#507

知道如何在index.js中解决此内容类型问题吗?

index.js

 (function () {
  'use strict';

  const fs = require('fs');
  const elasticsearch = require('elasticsearch');
  const esClient = new elasticsearch.Client({
    host: 'localhost:9200',
    log: 'error'
  });

  const bulkIndex = function bulkIndex(index, type, data) {
    let bulkBody = [];

    data.forEach(item => {
      bulkBody.push({
        index: {
          _index: index,
          _type: type,
          _id: item.id
        }
      });      
      bulkBody.push(item);
    });

   esClient.bulk({body: bulkBody})
    .then(response => {
      console.log(`Inside bulk3...`);
      let errorCount = 0;
      response.items.forEach(item => {
        if (item.index && item.index.error) {
          console.log(++errorCount, item.index.error);
        }
      });
      console.log(`Successfully indexed ${data.length - errorCount} out of ${data.length} items`);
    })
    .catch(console.err);
  };

  // only for testing purposes
  // all calls should be initiated through the module
  const test = function test() {
    const articlesRaw = fs.readFileSync('data.json');
    const articles = JSON.parse(articlesRaw);
    console.log(`${articles.length} items parsed from data file`);
    bulkIndex('library', 'article', articles);
  };

  test();

  module.exports = {
    bulkIndex
  };
} ());

我的本地Windows环境:

java版 1.8.0_121
elasticsearch版本 6.1.1
节点版本 v8.9.4
npm版本 5.6.0

1 个答案:

答案 0 :(得分:3)

bulk函数不返回承诺。它接受回调函数作为参数。

esClient.bulk(
  {body: bulkBody},
  function(err, response) {
    if (err) { console.err(err); return; }
    console.log(`Inside bulk3...`);
    let errorCount = 0;
    response.items.forEach(item => {
      if (item.index && item.index.error) {
        console.log(++errorCount, item.index.error);
      }
    });
    console.log(`Successfully indexed ${data.length - errorCount} out of ${data.length} items`);
  }
)

或使用promisify将接受(err, value) => ...样式回调的函数转换为返回promise的函数。

const esClientBulk = util.promisify(esClient.bulk)
esClientBulk({body: bulkBody})
  .then(...)
  .catch(...)

编辑:刚刚发现elasticsearch-js supports both回调和承诺。所以这应该不是问题。

通过查看您已关联的项目的package.json,它使用的是elasticsearch-js版本^11.0.1,这是一个旧版本,并且正在使用application/x-ldjson发送请求批量上传的标头,更新的弹性搜索版本为not supported。因此,将elasticsearch-js升级到较新版本(当前最新版本为14.0.0)应该会修复它。