设计灵活高效的问答系统

时间:2012-02-12 08:43:05

标签: c# sql design-patterns database-design

我一直在研究一个动态的问答系统,但是我在为这个系统创建一个高效灵活的设计时遇到了麻烦。我很想知道是否有既定的设计模式或任何有关设计该系统的建议。

我正在尝试做什么

我有一系列问题。在回答之后,会显示另一组问题,取决于前一组的答案。这个重复,直到不再需要问题为止。

问题的答案都是布尔值,多项选择或数字。

重要的部分是大多数问题仅在满足一组特定条件时才显示,具体取决于之前的答案。
我需要标准来支持主要的布尔逻辑,例如And,Or,Not,Equals,Greater Than和Less Than。

例如,假设我已收到AgeGenderState等问题的答案。
下一个问题之一是In School?,但只有在以下情况下才能显示:Age < 30 AND Gender=Male AND (State = CA OR State = NY)

有没有人听说过类似的设计模式?你会如何处理这种设计?


背景资料

我尝试了数据库列

起初,我们只有3个初始问题,因此我们只使用3列来过滤第二组问题。

然而,我们的业务需求增长,我们开始需要更多初始问题,添加更多列,并在这些过滤器中添加更多逻辑。

这很快就变得太僵硬和麻烦。

我尝试过Logic Interpreter

我们第二次尝试使系统更加灵活:将过滤逻辑存储为JavaScript,并运行JavaScript解释器来过滤结果。

这对于灵活性非常有效,但是从数据库中检索数千行并解释脚本的效率非常低,并且对于生产来说效果太差。

我尝试过混合

我们最终结合了这两种方法,并提出了可行的方法 我们首先根据几个硬编码的数据库列过滤我们的列表,然后使用JavaScript解释器进一步过滤列表。

这种混合系统仍有许多缺点:

  • 逻辑在两个不同的系统(SQL数据库逻辑和JavaScript解释器)
  • 解释JavaScript很慢,并且对于所需的简单布尔逻辑来说可能有点过分了
  • 系统很难维护,特别是因为JavaScript逻辑必须始终由开发人员编写。

我真的很想听听如何改进这种设计的建议。

其他信息

我的数据库是MS SQL Server,后端是.NET C#,JavaScript解释器是JINT。 UI实现并不重要,但它是一个支持AJAX的网站,用于询问和回答这些问题。

3 个答案:

答案 0 :(得分:3)

我们过去必须为医疗系统做类似的事情,由于其复杂性,我们采用了重用支持多分类决策树的规则引擎。我记得我遇到过一个很简单的设计,并设法挖掘出这个链接。

http://www.javaworld.com/javaworld/javatips/jw-javatip139.html?page=1

设计与数据存储松散耦合,因此可以轻松融入现有的解决方案设计。

答案 1 :(得分:1)

如果我正确理解您的问题,听起来您正在构建finite state machine

每个州对应一个问题,并根据答案继续讨论新问题。在几个不同的州可能会出现同样的问题。

在你的例子中,开始状态是问题“状态?”,如果答案是“CA”,我们移动到下一个状态,问题是“租或自己?”。对于该问题的任何答案,下一个状态将是“年龄?”的问题。因为“州”没有进一步的子问题 - >&gt;“租还是拥?”路径。

对于db模型,您需要状态表和状态之间的关系表,即:

表状态:

  • id(int)
  • question(varchar)
  • type(set [text,boolean,int])

表state_state:

  • fromState(int)
  • 使用toState(int)的
  • answerType(设置[any,equals,greater,...])
  • 回答(varchar)

在您的代码中,您只需要知道当前状态,提出问题,查询state_state并将结果与​​给出的答案进行比较,以了解下一个状态的ID将是什么,从而成为下一个问题。< / p>

如果您有很多具有相同问题的州,您可以创建一个问题表并将其与州相关联。

如果您有几个“开始问题”,您可以拥有一个状态机并将结束问题与下一个“开始问题”联系起来,或者您可以拥有多个状态机。

答案 2 :(得分:0)

我们有类似的要求来创建自定义调查。我们有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
)