我将使用大学的图书馆系统来解释我的用例.学生在图书馆系统中注册,提供他们的个人资料:性别,年龄,部门,以前完成的课程,目前注册的课程,已借阅的书籍等.图书馆系统中的每本书都将根据学生的资料来定义一些借阅规则,例如,计算机算法教科书只能由目前在该类注册的学生借用;另一本教材只能由数学部门的学生借用;也可能有一些规则,让学生最多只能借用2台电脑网络书.由于借用规则,当学生在图书馆系统中进行搜索/浏览时,他只会看到他可借的书籍.所以,这个要求真的归结为有效地生成学生有资格借用的书籍清单.
以下是我如何使用Drools来设计设计 – 每本书将有一个对学生资料作为LHS的几个领域约束的规则,书籍规则的RHS只是将书籍ID添加到全局结果列表中,然后是所有书籍规则被加载到RuleBase中.当学生搜索/浏览图书馆系统时,会从RuleBase创建无状态会话,并将学生的个人资料称为事实,然后学生可以借用的每本书将触发其书籍规则,并获得完整的图书列表学生可以借用全球成绩单.
几个假设:图书馆将处理数百万本书;我不期望书规则太复杂,每个规则最多只有3个简单的字段约束;系统需要处理的学生人数在100K左右,所以负载相当沉重.我的问题是:如果加载了一百万本书规则,Drools会记录多少内存?所有这些百万条规则将会有多快?如果Drools是合适的,我想听听有经验的用户设计这样一个系统的最佳实践.谢谢.
解决方法
首先,不要为每本书制定规则.制定限制规定 – 与书籍相比限制的限制要少得多.这将对运行时间和内存使用产生巨大的影响.
通过规则引擎运行大量书籍将会变得昂贵.特别是因为您不会向用户显示所有结果:每页只有10-50个.想到的一个想法是使用规则引擎构建一组查询条件. (我实际上不会这样做 – 见下文)
这是我想到的:
rule "Only two books for networking" when Student($checkedOutBooks : checkedOutBooks),Book(subjects contains "networking",$book1 : id) from $checkedOutBooks,id != $book1) from $checkedOutBooks then criteria.add("subject is not 'networking'",PRIORITY.LOW); end rule "Books allowed for course" when $course : Course($textbooks : textbooks),Student(enrolledCourses contains $course) Book($book : id) from $textbooks,then criteria.add("book_id = " + $book,PRIORITY.HIGH); end
但我实际上不会这样做!
这是我如何改变问题:
不向用户显示书籍是一种糟糕的经历.用户可能想要仔细阅读这些书籍,看看下一次要下载哪些书籍.显示书籍,但不允许结帐受限制的书籍.这样,每个用户一次只能运行1-50本书来执行规则.这将是相当zippy.上述规则将成为:
rule "Allowed for course" activation-group "Only one rule is fired" salience 10000 when // This book is about to be displayed on the page,hence inserted into working memory $book : Book(),$course : Course(textbooks contains $book),Student(enrolledCourses contains $course),then //Do nothing,allow the book end rule "Only two books for networking" activation-group "Only one rule is fired" salience 100 when Student($checkedOutBooks : checkedOutBooks),id != $book1) from $checkedOutBooks,// This book is about to be displayed on the page,hence inserted into working memory. $book : Book(subjects contains "networking") then disallowedForCheckout.put($book,"Cannot have more than two networking books"); end
我正在使用激活组来确保只有一个规则被触发,并且显着地确保它们按照我想要的顺序触发.
最后,保持规则缓存. Drools允许 – 并建议 – 您只将规则加载到知识库中,然后从中创建会话.知识库昂贵,会话便宜.