Ошибка NewLine в массовом API-запросе Elasticsearch - PullRequest
1 голос
/ 12 апреля 2020

Я пытаюсь использовать API-интерфейс эластичного поиска для вставки нескольких записей в индекс. Мой JSON выглядит примерно так: запрос json

Я вставляю новую строку (\\n) в конец документа, но я все еще получаю newline error.

    Error: {
        "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
    }

Ответы [ 2 ]

0 голосов
/ 12 апреля 2020

На основании моего предыдущего ответа и { ссылка }:

const AWS = require('aws-sdk');
const creds = new AWS.EnvironmentCredentials('AWS');

const INDEX_NAME = 'index_name';

const esDomain = {
    region: 'us-east-1',
    endpoint: 'yoursearchdomain.region.amazonaws.com',
    index: 'myindex',
    doctype: 'mytype'
};

const endpoint = new AWS.Endpoint(esDomain.endpoint);
const req = new AWS.HttpRequest(endpoint);


const docs_as_body_params = JSON.parse(
    '[' +
    `{"index":{}} {"tags":["ab","cd"],"question":"test this","answer":"answer first"} {"index":{}} {"tags":["de","fg"],"question":"test second","answer":"answer second"}`.split(
        /(\s?{"index":{}} )/g
    )
    .filter(match => match.length)
    .filter((_, index) => index % 2 !== 0) +
    ']'
);

const bulk_body = [];
docs_as_body_params.map((doc) => {
    bulk_body.push({
        index: {
            _index: INDEX_NAME,
            _id: doc.id || null
        }
    });
    bulk_body.push(doc);
});

/// THE MOST IMPORTANT PART -- getting to a valid ndjson
const ndjson_payload = bulk_body.map(JSON.stringify).join('\n') + '\n'

req.method = 'POST';
req.path = '_bulk'
req.region = esDomain.region;
req.headers['presigned-expires'] = false;
req.headers['Host'] = endpoint.host;
req.headers['Content-Type'] = 'application/json';
req.body = ndjson_payload;

var signer = new AWS.Signers.V4(req, 'es');
signer.addAuthorization(creds, new Date());

var send = new AWS.NodeHttpClient();
send.handleRequest(req, null, function (httpResp) {
    var respBody = '';
    httpResp.on('data', function (chunk) {
        respBody += chunk;
    });
    httpResp.on('end', function (chunk) {
        console.log('Response: ' + respBody);
        context.succeed('Lambda added document ' + doc);
    });
}, function (err) {
    console.log('Error: ' + err);
    context.fail('Lambda failed with error ' + err);
});
0 голосов
/ 12 апреля 2020

Ваш json был nd-json (с разделителями новой строки) JSON в какой-то момент, но выглядит все испорченным сейчас, поэтому нам придется сделать некоторую очистку заранее.

Initialize:

const {
    Client
} = require("@elastic/elasticsearch");

const client = new Client({
    node: 'http://localhost:9200'
});

const INDEX_NAME = 'index_name';

Преобразовать потенциальный nd json в массив или объекты расходных материалов:

const docs_as_body_params = JSON.parse(
    '[' +
    `{"index":{}} {"tags":["ab","cd"],"question":"test this","answer":"answer first"} {"index":{}} {"tags":["de","fg"],"question":"test second","answer":"answer second"}`.split(
        /(\s?{"index":{}} )/g
    )
    // filter out empty strings
    .filter(match => match.length)
    // take every odd member (skipping `{"index":{}}`)
    .filter((_, index) => index % 2 !== 0) +
    ']'
);

Построить объемное тело

const bulk_body = [];
docs_as_body_params.map((doc) => {
    bulk_body.push({
        index: {
            _index: INDEX_NAME,
            _id: doc.id || null
        }
    });
    bulk_body.push(doc);
});

Выполнить массовое индексирование:

client.bulk({
        body: bulk_body
    },
    (err, resp) => {
        if (err || resp.errors) {
            console.err(err || resp.errors)
        }
        console.info(resp.body.items);
    }
);
...