【问题标题】:How to index a JSON document directly from memory如何直接从内存中索引 JSON 文档
【发布时间】:2017-08-14 14:39:05
【问题描述】:

我正在尝试为 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 对象,但没有一个示例,而且到目前为止我尝试过的任何方法似乎都不起作用。好像是bug?

更新:通过保存到一个临时文件,然后使用createDataStream(),而不是readFileSync(),它可以工作,但它仍然是一个很大的麻烦,必须通过磁盘获取已经在内存中的信息。

我也试过create a in-memory stream from a 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'

【问题讨论】:

    标签: json node.js watson watson-discovery


    【解决方案1】:

    该服务检查文件名,然后检查内容以确定类型,但似乎无法正确识别 JSON 内容 - 它只看到文本。只要文件名以.json 结尾(它不关心contentType),另一个答案就可以了。

    但是,我们在 node.js SDK 中添加了 .addJsonDocument().updateJsonDocument() 方法以使其更加简单:

    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);
    });
    

    【讨论】:

    • 嗨@Nathan Friedly,我删除了我的答案,因为你的答案更完整并且具有最佳实践的最新更新。谢谢
    【解决方案2】:

    您遇到的问题是因为缺少内容类型(默认为 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)
    

    【讨论】:

    • 我明白了……这似乎没有出现在文档中。今天晚些时候我会看看它;谢谢。
    • 顺便说一句,它是文件名,而不是使这项工作的 contentType。但是,Node.js SDK 现在有 .addJsonDocument() 和 .updateJsonDocument() ,这让它更简单一些。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-28
    • 2016-04-30
    相关资源
    最近更新 更多