规则匹配引擎——思路1

来源:互联网 发布:mysql导出表结构步骤 编辑:程序博客网 时间:2024/05/22 04:24

题记:项目需求,当然是项目需求,我要实现一个规则匹配引擎,匹配数据的属性并进行后续操作。数据属性可灵活定制,且要预留足够的扩展方法,性能也有严格的要求。经过1个月的努力,顺利完成目标,我对自己的工作还是非常满意的。成就不只是最后的引擎,更重要的是设计和实现引擎过程中的思考和学习到的东西。自己的思路兜兜转转,造就了最后的结果,可对于我一个懒人,我总想效益最大化,因此想把整个分析思路写下来,帮自己梳理的更清楚,学习固化的更快。项目有可能是一锤子的买卖,可我的成果不是。


要实现一个规则匹配引擎,对于给定数据,在规则中查找匹配成功的条目,并执行相应的操作。待匹配数据是最简单的key-value对,比如:

{'name': 'fucking', 'time': '10:00:00', 'location': 'Beijing', 'action': 'Buy', 'price': '100.00'}

表示在金正日同学在10点钟整在Beijing买了100.00快钱的东西。

规则则是数据所含属性的各种组合,比如:

{'name': '$any', 'time': '$any', 'location': 'Beijing;Shanghai', 'action': 'Buy', 'price': '>50.00'}

表示无论是谁在什么时间,在北京或者上海,买了大于50.00的东西。对满足此规则的数据,我们可以给它一个comment叫“烧包”,然后执行相应的action“格杀勿论”。


具体给什么样的comment和action都是简单的事情,问题在于对于接踵而至的待匹配数据,我们怎么样快速的判断出其是不是符合我们之前设定的规则。


最简单的方法就是自上而下一条一条规则比对,如果只有10条规则,每条规则的判断需要6秒,而恰好待判断数据的到来也非常配合的满足<1条/分钟,并且在可预期的将来,规则属性项和规则条数都不会变化,那这种方法简直就是最优的!简单易懂易实现,还能要求更多么。现实中有这样的情况,只可惜我碰到的不是,大多数人碰到的也不是。

那该怎么办?

尽管我们成长在一个辩证看问题的和谐社会,但科学的发展是形而上的,那就让我们把问题简单化吧。

数据:

{'price': '100.00'}

规则:

{'price': '>50.00'}

对于一个数字,我们如果要判断其是否符合某个范围,最简单的方法也仍然是比较。但是,如果有两条甚或更多的规则列举在这里,我们或许能想到些什么:

1. {'price': '>50.00'} 2. {'price': '>150.00'} 3. {'price': '<75.00'}

此时,我们能明了的看到,当满足规则2的数据,一定能满足规则1,反之不成立;当满足条件2的规则,一定不能满足条件3,反之成立。或许还有更多,但想到这些,我觉得我已经比简单的单条匹配聪明一点了。

为什么会有如上所说的条件间的这种正向或者反向的关系呢? “满足规则2的数据,一定能满足规则1”是因为条件1的范围包含条件2,因此属于2的范围里的数据,必然属于1的范围;“满足条件2的规则,一定不能满足条件3”是因为条件2和条件3没有任何交集,成就了一个,另一个必然不成。

也就是说,各个规则间可能存在着包含,相交,相异,互斥等关系,这些关系是我们可以利用的信息,通过对这些信息的预处理,我们可以最大化的利用一次比较的结果来消除杂音,避免其它不必要的比较损耗。

——这貌似已经扯到了信息论,事实上这就是信息论。但是这问题还不应该上升到这么高的理论高度,所以就此打住。

问题改变了,我们该如何有效的使用这些规则间的关系呢?

不急,慢慢分析: 

    若首先匹配规则1,成功 -> 照常匹配2、3;失败 -> 2、3满足

    若首先匹配规则2,成功 -> 满足2,不满足3;失败 -> 照常匹配1、3

    若首先匹配规则3,成功 -> 照常匹配1,2不满足;失败 -> 满足1,照常匹配2

有点乱,明儿再说。