设计一个灵活高效的问答系统
本文关键字:高效 问答系统 一个 | 更新日期: 2023-09-27 18:24:16
我一直在开发一个动态问答系统,但我很难为这个系统创建高效灵活的设计。我很想知道是否有一个既定的设计模式或设计这个系统的任何建议。
我想做什么
我有一系列问题。回答完这些问题后,会显示另一组问题,取决于前一组问题的答案。重复这种情况,直到不再需要提问为止。
问题答案都是布尔型、多项选择题或数字型。
重要的一点是,大多数问题只有在满足一组特定标准时才会显示,这些标准是基于以前的答案
我需要主要支持布尔逻辑的标准,如And、Or、Not、Equals、Greater Than和Less Than。
例如,假设我已经收到了Age
、Gender
和State
等问题的答案
下一个问题之一是In School?
,但它应该仅在以下情况下显示:Age < 30 AND Gender=Male AND (State = CA OR State = NY)
有人听说过类似的设计模式吗?你会如何处理这个设计
背景信息
我尝试过数据库列
起初,我们只有3个初始问题,所以我们只使用3列来过滤第二组问题。
然而,我们的业务需求不断增长,我们开始需要更多的初始问题,添加更多的列,并在这些过滤器中添加更多的逻辑。
这很快变得过于死板和繁琐。
我试过一个逻辑解释器
我们的第二个尝试是使系统更加灵活:将过滤逻辑存储为JavaScript,并运行JavaScript解释器来过滤结果。
这在灵活性方面非常有效,但从数据库中检索数千行并解释脚本效率极低,而且对于生产来说执行得太差。
我试过混合动力车
我们最终把这两种方法结合起来,想出了一些可行的办法
我们首先根据几个硬编码的数据库列过滤列表,然后使用JavaScript解释器进一步过滤列表。
这种混合系统仍然有许多缺点:
- 逻辑在两个不同的系统中(SQL数据库逻辑和JavaScript解释器)
- 解释JavaScript很慢,对于所需的简单布尔逻辑来说可能有些过头了
- 该系统很难维护,尤其是因为JavaScript逻辑必须始终由开发人员编写
我真的很想听听关于如何改进这个设计的建议。
其他信息
我的数据库是MS SQL Server,后端是.NET C#,JavaScript解释器是JINT。UI实现并不重要,但它是一个启用AJAX的网站,用于询问和回答这些问题。
我们过去不得不对医疗系统做类似的事情,由于其复杂性,我们不得不重用支持多分类决策树的规则引擎。我记得我遇到了一个很好的简单设计,并设法挖掘出了链接。
http://www.javaworld.com/javaworld/javatips/jw-javatip139.html?page=1
该设计与数据存储松散耦合,因此很容易适应现有的解决方案设计。
如果我正确理解你的问题,听起来就像你在构建一个有限状态机。
每个状态对应一个问题,然后根据答案进入一个新问题。同样的问题可能出现在几个不同的州。
在您的示例中,开始状态将是问题"state?",如果答案是"CA",我们将转到下一个状态,并提出问题"Rent or Own?"。对于该问题的任何答案,下一个状态将是问题"年龄?",因为"状态?"->"出租还是拥有?"路径没有其他子问题。
对于数据库模型,您需要一个状态表和状态之间的关系表,即:
表格状态:
- id(int)
- 问题(varchar)
- type(set[text,boolean,int])
表状态:
- fromState(int)
- toState(int)
- answerType(设置[any,equals,greater,…])
- 答案(varchar)
在您的代码中,您只需要知道当前状态,提出问题,对state_state进行查询,并将结果与给出的答案进行比较,就可以知道下一个状态的id是什么,从而了解下一个问题。
如果你有很多州都有相同的问题,你可以创建一个问题表,并将其与州联系起来。
如果你有几个"开始问题",你可以有一个状态机,并将结束问题与下一个"开始问题"联系起来,也可以有几个状态机。
我们也有创建自定义调查的类似要求。我们有3张表,问题,回答和提问路线。响应表允许您为每个问题创建多个答案,questionroute表允许您根据特定的响应选择下一个问题。
CREATE TABLE [dbo].[Question]
(
QuestionID uniqueidentifier,
[Text] varchar(512)
)
CREATE TABLE [dbo].[Response]
(
ResponseID uniqueidentifier,
QuestionID uniqueidentifier,
[Text] varchar(512)
)
CREATE TABLE [dbo].[QuestionRoute]
(
QuestionRouteID uniqueidentifier,
QuestionID uniqueidentifier,
ResponseID uniqueidentifier,
NextQuestionID uniqueidentifier
)