Как индексировать документ JSON прямо из памяти

Я пытаюсь проиндексировать документ JSON, но он просто не работает; до сих пор я пробовал решения, опубликованные в https://developer.ibm.com/answers/questions/361808/adding-a-json-document-to-a-discovery-collection-u/ , но это просто не работа;

Если я попытаюсь:

    discovery.addDocument({
        environment_id: config.watson.environment_id,
        collection_id: config.watson.collection_id,
        file: JSON.stringify({
            "ocorrencia_id": 9001
        })
    }, (error, data) => {
        if (error) {
            console.error(error);
            return;
        }

        console.log(data);
    });

Он возвращает мне эту ошибку:

    The Media Type [text/plain] of the input document is not supported. Auto correction was attempted, but the auto detected media type [text/plain] is also not supported. Supported Media Types are: application/json, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/pdf, text/html, application/xhtml+xml .

С другой стороны, если я попытаюсь:

    discovery.addDocument({
        environment_id: config.watson.environment_id,
        collection_id: config.watson.collection_id,
        file: JSON.parse(JSON.stringify({
            "ocorrencia_id": 9001
        }))
    }, (error, data) => {
        if (error) {
            console.error(error);
            return;
        }

        console.log(data);
    });

Я получаю эту ошибку:

TypeError: source.on is not a function
    at Function.DelayedStream.create (C:\Temp\teste-watson\watson-orchestrator\node_modules\delayed-stream\lib\delayed_stream.js:33:10)
    at FormData.CombinedStream.append (C:\Temp\teste-watson\watson-orchestrator\node_modules\combined-stream\lib\combined_stream.js:43:37)
    at FormData.append (C:\Temp\teste-watson\watson-orchestrator\node_modules\form-data\lib\form_data.js:68:3)
    at appendFormValue (C:\Temp\teste-watson\watson-orchestrator\node_modules\request\request.js:324:21)
    at Request.init (C:\Temp\teste-watson\watson-orchestrator\node_modules\request\request.js:337:11)
    at new Request (C:\Temp\teste-watson\watson-orchestrator\node_modules\request\request.js:130:8)
    at request (C:\Temp\teste-watson\watson-orchestrator\node_modules\request\index.js:54:10)
    at createRequest (C:\Temp\teste-watson\watson-orchestrator\node_modules\watson-developer-cloud\lib\requestwrapper.js:177:10)
    at DiscoveryV1.addDocument (C:\Temp\teste-watson\watson-orchestrator\node_modules\watson-developer-cloud\discovery\v1.js:516:10)
    at client.query.then.res (C:\Temp\teste-watson\watson-orchestrator\populate\populate.js:36:13)
    at process._tickCallback (internal/process/next_tick.js:109:7)

Точно так же, сохранив во временный файл, а затем используя его:

    const tempy = require('tempy');
    const f = tempy.file({extension: 'json'});
    fs.writeFileSync(f, JSON.stringify({
            "ocorrencia_id": 9001
    }));

    discovery.addDocument({
        environment_id: config.watson.environment_id,
        collection_id: config.watson.collection_id,
        file: fs.readFileSync(f)
    }, (error, data) => {
        if (error) {
            console.error(error);
            return;
        }

        console.log(data);
    });

Тогда это происходит:

The Media Type [application/octet-stream] of the input document is not supported. Auto correction was attempted, but the auto detected media type [text/plain] is also not supported. Supported Media Types are: application/json, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/pdf, text/html, application/xhtml+xml .

Учитывая, что в других сообщениях рекомендуется использовать JSON.parse(), кажется, что API принимает объект JS, но ни один из примеров и ничего из того, что я пробовал до сих пор, не работает. Кажется, это ошибка?

Обновление: сохраняя во временный файл, а затем используя createDataStream() вместо readFileSync(), это работает, но все еще большая проблема, связанная с необходимостью просматривать диск для информации, которая уже находится в памяти.

Я также попытался создать поток в памяти из Readable, но это тоже не работает:

    var Readable = require('stream').Readable;
    var s = new Readable();
    s._read = function noop() {}; // redundant? see update below
    s.push(JSON.stringify({
            "ocorrencia_id": 9001
    }));        
    s.push(null);

    discovery.addDocument({
        environment_id: config.watson.environment_id,
        collection_id: config.watson.collection_id,
        file: s
    }, (error, data) => {
        if (error) {
            console.error(error);
            return;
        }

        console.log(data);
    });

Этот терпит неудачу с:

Error: Unexpected end of multipart data
    at Request._callback (C:\Temp\teste-watson\watson-orchestrator\node_modules\watson-developer-cloud\lib\requestwrapper.js:88:15)
    at Request.self.callback (C:\Temp\teste-watson\watson-orchestrator\node_modules\request\request.js:188:22)
    at emitTwo (events.js:106:13)
    at Request.emit (events.js:191:7)
    at Request.<anonymous> (C:\Temp\teste-watson\watson-orchestrator\node_modules\request\request.js:1171:10)
    at emitOne (events.js:96:13)
    at Request.emit (events.js:188:7)
    at Gunzip.<anonymous> (C:\Temp\teste-watson\watson-orchestrator\node_modules\request\request.js:1091:12)
    at Gunzip.g (events.js:292:16)
    at emitNone (events.js:91:20)
    at Gunzip.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickCallback (internal/process/next_tick.js:104:9) code: 500, error: 'Unexpected end of multipart data'

person Haroldo_OK    schedule 14.08.2017    source источник


Ответы (2)


Служба проверяет имя файла, а затем содержимое, чтобы определить тип, но, похоже, не распознает содержимое JSON правильно — он просто видит текст. Другой ответ будет работать, если имя файла заканчивается на .json (он не заботится о contentType).

Однако мы добавили .addJsonDocument() и .updateJsonDocument() к узлу. js SDK, чтобы сделать это еще проще:

discovery.addJsonDocument({
    environment_id: config.watson.environment_id,
    collection_id: config.watson.collection_id,

    // note: no JSON.stringify needed with addJsonDocument()
    file: { 
        "ocorrencia_id": 9001
    }
}, (error, data) => {
    if (error) {
        console.error(error);
        return;
    }

    console.log(data);
});
person Nathan Friedly    schedule 14.08.2017
comment
Привет @Nathan Friedly, я удалил свой ответ, потому что ваш ответ более полный и имеет последнее обновление с лучшими практиками. Спасибо - person Sayuri Mizuguchi; 14.08.2017

Проблема, с которой вы столкнулись, связана с отсутствующим типом контента (по умолчанию text/plain). Когда вы предоставляете документ для загрузки в виде строки, вам необходимо указать тип содержимого и имя файла вместе с ним. В этом случае вы можете попробовать использовать следующее для своей цели

discovery.addDocument({
  //other required parameters 
  file: {
    value: JSON.stringify({ "ocorrencia_id": 9001 }),
    options: {
      filename: "some_file_name",
      contentType: "application/json; charset=utf-8"
    }
  } 
}, callbackFn)
person User10001    schedule 14.08.2017
comment
Ясно... похоже, в документации этого нет. Я посмотрю на это позже сегодня; Благодарю. - person Haroldo_OK; 14.08.2017
comment
Кстати, это имя файла, а не contentType, делает эту работу. Но в Node.js SDK теперь есть .addJsonDocument() и .updateJsonDocument(), которые делают его более простым. - person Nathan Friedly; 14.08.2017