首页 文章

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

提问于
浏览
0

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

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

在尝试从data.json导入1000个项目的数据时,执行'node 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 Headers #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 回答

  • 2

    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(...)
    

    EDIT: 刚刚发现了elasticsearch-js supports both回调和承诺 . 所以这应该不是问题 .

    通过查看您链接的项目的 package.json ,它使用 elasticsearch-js version ^11.0.1 这是一个旧版本,并且发送带有 application/x-ldjson 标头的请求进行批量上传,这是由较新的elasticsearch版本not supported . 因此,将 elasticsearch-js 升级到更新版本(当前最新版本为 14.0.0 )应该修复它 .

相关问题