【问题标题】:Watson Conversation - Oracle DB IntegrationWatson 对话 - Oracle 数据库集成
【发布时间】:2018-03-27 15:33:23
【问题描述】:

早上好/下午好,我正在尝试让 Watson 返回从我们的 Oracle 数据库手动设置的响应。

我使用异步顺序访问数据库并返回响应,因为我遇到的第一个问题是数据库查询在 Watson 已经返回响应之后才会发生。 Async.waterfall 解决了这个问题。

我当前的问题:在控制台中,我看到所有内容都已正确记录。查询数据库,response.output.text 设置正确,然后返回给 Watson,但我的聊天中没有出现任何响应。如果我在异步之前设置 response.output.text = "asdfa",asdfa 会按预期返回.

我在试图弄清楚这一点时不知所措,所以我很感激任何和所有的帮助。如果需要更多信息,请告诉我。

  // Send the input to the conversation service
conversation.message(payload, function (err, data) {
if (err) {
return res.status(err.code || 500).json(err);
}
return res.json(updateMessage(payload, data));
});
});

function updateMessage(input, response) {
 var responseText = null;
 if (!response.output) {
 response.output = {};
} else {
// checkNames check
if (response.output.nodes_visited[0] === 'slot_11_1519333387192' && response.entities[0].entity === 'confirm') {

  /* This code actually returns asdfa as a response from Watson.. */
  // response.output.text = "asdfa";
  // return response;
  async.waterfall([
      // this function queries the database
      // TODO: module out the Oracle connection parts once POC is completed
      function queryDB(callback) {
        console.log('Starting queryDB');
        var query = "SELECT column_name FROM table@prod WHERE column_id = '" + response.context.VSUID + "'";
        oracledb.getConnection('hr',
          function (err, connection) {
            var conn = oracleGetConnection(err, connection);
            conn.execute(query, {}, {
                outFormat: oracledb.OBJECT
              },
              function (err, result) {

                console.log('result from Oracle: ', result);
                // pass a null error and the result of the query

                callback(null, result.rows[0]);
              });
          });
      },
      // this function formats the result of the query
      // TODO: this should not be it's own function. This can happen at the same time the db gets the row 
      function formatName (arg1, callback) {
        console.log('this should happen after query..');
        console.log('arg1: ', arg1);

        var r = JSON.stringify(arg1);
        r = r.substring((r.indexOf(':') + 1) + 1, r.length - 2);
        console.log('Name is: ', r);
        // pass a null error and the formatted name
        callback(null, r);
      }
    ],
    // Final function to be ran after the two above have completed 
    function finalFunction (err, result) {
      if (err) {
        console.log('uh oh async err: ', err);
      } else {
        console.log('This is final Function');
        // set output text
        response.output.text = 'Is your name ' + result + '?';
        // response.context.dbResponse = 'Is your name ' + result + '?';
        // response.output.text = "asdfasdfasd";
        // console.log('This is the value of response\n\n', response);
        // var resp = returnResponse(input, response);
        response.context.dbResponse = response.output.text[0];
        return returnResponse(input, response);
        // return response;
      }
    });
    // response.output.text = "asdfa";
    console.log('This is response.output.text ', response.output.text);
    return response;
} else {
  //If no special if case to query the db just run Watson Conversation stock
  return returnResponse(input, response);
}

} }

这是一个示例控制台日志。

This logs the Input from the user:
name 111111111
This logs the Response from Watson:
Is 111111111correct?
This logs the intent recognized, if any:
nameCheck
This logs the entity recognized, if any:
VSUID
This logs the text that is being returned to the user:  [ 'Is 111111111correct?'
]
Starting queryDB
Connected to database
result from Oracle:  { outBinds: undefined,
  rowsAffected: undefined,
  metaData: [ { name: 'TABLE_FIRST_NAME' } ],
  rows: [ [ 'Tyler' ], [ 'Tyler' ] ],
  resultSet: undefined }
this should happen after query..
arg1:  [ 'Tyler' ]
Name is:  "Tyler
This is final Function
This logs the Input from the user:
yes
This logs the Response from Watson:
Is your name "Tyler?
This logs the entity recognized, if any:
confirm
This logs the text that is being returned to the user:  Is your name "Tyler? 

【问题讨论】:

    标签: javascript node.js api watson-conversation watson


    【解决方案1】:

    编写如下代码会使您面临 SQL 注入漏洞(以及可能的性能问题):

    var query = "SELECT column_name FROM table@prod WHERE column_id = '" + response.context.VSUID + "'";
    

    请阅读section of the documentation on bind variables

    关于你的问题...

    您将updateMessage 视为一个同步函数,但它正在执行异步工作。执行异步工作的函数需要异步 API,例如 Node.js 样式的回调、Promises 或 AsyncFunctions (async/await)。

    如果您看到您提供的代码的第 73 行,则表示您正在“返回”响应对象,但这不在 async.waterfall 调用范围内。由于 Node.js 的异步特性,即使是第 67 行的返回也不起作用。

    这是我描述所有这些工作原理的最新尝试: https://www.youtube.com/watch?v=iAdeljxq_hs

    您可以在此处访问幻灯片和示例代码: https://www.dropbox.com/s/quu7oxiug0gh6ua/Understanding%20Async%20Processing%20and%20Patterns%20in%20Node.js.zip?dl=0

    在示例代码的 code> header-detail 目录中,您会看到以 header-detail-with- 开头的 5 个不同的文件,但您可以做出不同的 API 选择。您将不得不对您的updateMessage API 做出类似的选择。

    要运行测试,请使用 ddl.sql 文件创建目标表,然后根据环境需要编辑 db-config.js,最后运行node test.js 1 来自该目录中的终端。您可以更改末尾的数字以运行不同的测试文件。

    【讨论】:

    • 丹,你太棒了。
    • 我看过你的视频(顺便说一句,一个很棒的概述,你杀了它)并使用你的示例代码重建了我的异步调用。遗憾的是,我遇到了同样的问题,因为我的数据库代码依赖于来自 Watson 的“响应”对象,无论我如何实现它,似乎响应是在异步调用完成之前返回的。这是当前代码 hastebin.com/zolesiforu.js 。我想从逻辑上知道我应该如何处理这个......谢谢!
    • 看看这是否有帮助:hastebin.com/hifoguhono.js 我无法测试它的语法错误等,但也许它会给你这个想法......
    • 在对代码进行了一些修改后,我让它工作了,丹!你得到的帮助比我所能获得的任何支持都多,这太疯狂了。谢谢!!谢谢!!谢谢!!
    • 很高兴听到这个消息!
    猜你喜欢
    • 2018-04-19
    • 1970-01-01
    • 2019-08-31
    • 2019-05-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多