我正在使用节点js来构建聊天机器人。
我目前正在将会话数据存储到Microsoft默认存储中,每个用户会话的限制为64K。我想使用自己的存储来存储会话数据。 Here是我从Microsoft开发人员那里得到的帮助。
我可以存储在文档DB和Azure表中。
不过,我很困惑。我们如何实现IStorageClient
接口存储在自己的数据库中?
每当我设置session.UserData.name=""
时,它应该存储在自己的数据库中。
答案 0 :(得分:3)
我不确定我是否得到了这个问题;我明白你要做的是什么,似乎你已经完成了所有的工作。
首先,您必须实现IStorageClient接口。在您的实现中,您编写逻辑以在数据库中存储内容。
您可以查看DocumentDB和Azure Tables实施,以了解如何实施。
现在,问题是..如果您的自定义存储位于Azure ...中,那么您可以将AzureBotStorage与自定义存储客户端一起使用。您实例化自定义存储客户端,传递对AzureBotStorage
的引用并将其设置为bot中的存储
// Azure DocumentDb State Store
var docDbClient = new azure.DocumentDbClient({
host: process.env.DOCUMENT_DB_HOST,
masterKey: process.env.DOCUMENT_DB_MASTER_KEY,
database: process.env.DOCUMENT_DB_DATABASE,
collection: process.env.DOCUMENT_DB_COLLECTION
});
var botStorage = new azure.AzureBotStorage({ gzipData: false }, docDbClient);
// Set Custom Store
bot.set('storage', botStorage);
如果您的自定义存储位于Azure之外的任何其他位置,则AzureBotStorage
可能不适合您。请注意,我不确定这一点,您必须检查代码以确认。从我看到的,它看起来非常通用,因此您可以重用它并只实现IStorageClient
。如果不是这样,您还必须实现IBotStorage接口。
最后,AzureBotStorage
正在这样做。它实现IBotStorage
并使用IStorageClient
与实际提供者进行交互。
答案 1 :(得分:2)
我编写代码将bot数据存储到Mongo Db中。 完整的代码和详细信息可以在BotBuilder-MongoDB
中找到IstorageClient 接口实现代码:
"use strict";
var Consts = require('./Consts');
var mongodb_1 = require("mongodb");
var replaceDot_Atrate = require("./replaceDot");
var mongoDbConnection = require('./connection.js');
var conf = require('../config');
var conversational_collname = conf.db.conversationalCollection;
var IStorageClient = (function () {
function IStorageClient(options) {
this.options = options;
}
IStorageClient.prototype.retrieve = function (partitionKey, rowKey, callback) {
var id = partitionKey + ',' + rowKey;
if(rowKey!=="userData"){
var query={"$and":[{"userid":id}]}
mongoDbConnection(function(err,db) {
var iterator= db.collection(conversational_collname).find(query);
iterator.toArray(function (error, result, responseHeaders) {
if (error) {
console.log("Error",error)
callback(error, null, null);
}
else if (result.length == 0) {
callback(null, null, null);
}
else {
var document_1 = result[0];
var finaldoc=replaceDot_Atrate.substituteKeyDeep(document_1, /\@/g, '.');
finaldoc["id"]=id
callback(null, finaldoc, null);
}
});
});
}
else{
var query={"$and":[{"userid":partitionKey}]}
mongoDbConnection(function(err,db) {
var iterator= db.collection(conversational_collname).find(query);
iterator.toArray(function (error, result, responseHeaders) {
if (error) {
callback(error, null, null);
}
else if (result.length == 0) {
//console.log("result length 0")
callback(null, null, null);
}
else {
var document_1 = result[0];
callback(null, document_1, null);
}
});
});
}
};
IStorageClient.prototype.initialize = function (callback) {
var _this = this;
var client=mongodb_1.MongoClient;
this.client = client;
mongoDbConnection(function(err,database) {
_this.database = database;
_this.collection = database.collection(conversational_collname);
callback(null);
});
};
IStorageClient.prototype.insertOrReplace = function (partitionKey, rowKey, entity, isCompressed, callback) {
var id=partitionKey + ',' + rowKey
var docDbEntity = { id: partitionKey + ',' + rowKey, data: entity, isCompressed: isCompressed };
if(rowKey!=="userData"){
var newEntitiy=replaceDot_Atrate.substituteKeyDeep(entity, /\./g, '@');
var conditions1 = {
'userid': id
};
var updateobj1 = {
"$set": {"data":newEntitiy,"isCompressed":false}
};
mongoDbConnection(function(error,db) {
db.collection(conversational_collname).update(conditions1,updateobj1,{upsert: true},function(err,res){
callback(error, null,"");
});
});
}
else{
var conditions = {
'userid': partitionKey
};
var update = {
"$set": {"data":entity}
}
mongoDbConnection(function(error,db) {
db.collection(conversational_collname).update(conditions,update,{upsert: true},function(err,res){
callback(error, null,"");
})
});
}
};
IStorageClient.getError = function (error) {
if (!error)
return null;
return new Error('Error Code: ' + error.code + ' Error Body: ' + error.body);
};
return IStorageClient;
}());
exports.IStorageClient = IStorageClient;
答案 2 :(得分:1)
这是对此库的另一种看法:mongo-bot-storage
import {MongoDbBotStorage, MongoDBStorageClient} from "mongo-bot-storage";
// use it like this
bot.set("storage", new MongoDbBotStorage(new MongoDBStorageClient({
url: "mongodb://localhost/mydb",
mongoOptions: {}
})));
// or like this
MongoClient.connect("mongodb://localhost/mydb", (error, db) => {
bot.set("storage", new MongoDbBotStorage(new MongoDBStorageClient({db})));
});
然后使用默认的session.userData
等等。
别忘了
// Enable Conversation Data persistence
bot.set('persistConversationData', true);
答案 3 :(得分:1)
我将这个答案发布在一个非常老的线程上,只是因为它似乎是实现Bot Framework自定义存储选项的最佳结果。
有一个非常简单的解决方案,它不涉及使用一段时间内未更新的npm,这会带来无法在公司环境中进行审核的风险,或者会使控制台中充满大量日志条目。
最简单的方法是按照Undocumented Guide for Custom Data Storage in Microsoft Bot Framework
中的步骤,使用最新的数据库驱动程序为您的机器人创建自己的数据存储代码。我花了一个小时左右的时间来实现MongoDB,其中包括一些针对最新驱动程序的学习曲线。
简而言之,万一链接消失了,您可以创建一个中间件,该中间件导出Bot Framework正在寻找的两个关键功能:getData
和saveData
。每一个都必须具有以下粗略结构(来自使用Redis的链接):
var storageKey = 'conversationId';
module.exports = {
getData : (data, callback) => {
redisClient.get(data[storageKey], (err, reply) => {
if (err || !reply) {
callback(err, null);
} else {
callback(null, JSON.parse(reply));
}
})
},
saveData : (data, value, callback) => {
redisClient.set(data[storageKey], JSON.stringify(value), (err, reply) => {
if (err) {
callback(err);
} else if (reply === 'OK') {
callback(null);
}
})
}
}
然后,请确保在app.js
中使用require()
中间件并进行相应设置:
const dbMiddleware = require('./path/to/middleware')
bot.set('storage', dbMiddleware)