我应该在这种情况下使用Drools吗? [英] Should I use Drools in this situation?

查看:215
本文介绍了我应该在这种情况下使用Drools吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将使用大学的图书馆系统来解释我的用例。学生在图书馆系统中注册并提供他们的个人资料:性别,年龄,部门,以前完成的课程,当前注册的课程,已经借阅的书籍等。图书馆系统中的每本书都将根据学生的个人资料定义一些借阅规则,例如,计算机算法的教科书只能由目前在该课程注册的学生借用;另一本教科书只能由数学系的学生借用;也可能有规则,学生最多只能借2本电脑网络书。由于借用规则,当学生在图书馆系统中搜索/浏览时,他只能看到他可以借用的书籍。因此,该要求实际上归结为有效生成学生有资格借阅的书籍清单。

I'll use a university's library system to explain my use case. Students register in the library system and provide their profile: gender, age, department, previously completed courses, currently registered courses, books already borrowed, etc. Each book in the library system will define some borrowing rules based on students' profile, for example, a textbook for the computer algorithm can only be borrowed by students currently registered with that class; another textbook may only be borrowed by students in the math department; there could also be rules such that students can only borrow 2 computer networking book at most. As a result of the borrowing rules, when a student searches/browses in the library system, he will only see the books that can be borrowed by him. So, the requirement really comes down to the line of efficiently generating the list of books that a student is eligible to borrow.

以下是我使用Drools进行设计的方法 - 每本书都有一个规则,对学生档案有一些字段限制作为LHS,书规则的RHS只是将书籍ID添加到全局结果列表,然后所有书籍规则被加载到RuleBase中。当学生搜索/浏览图书馆系统时,会从RuleBase创建无状态会话,并且学生的个人资料被断言为事实,然后学生可以借用的每本书都会触发其图书规则并获得完整的图书清单。学生可以在全球结果列表中借阅。

Here is how I vision the design using Drools - each book will have a rule with a few field constraints on the student profile as LHS, the RHS of the book rule simply adds the book id to a global result list, then all the book rules are loaded into a RuleBase. When a student searches/browsers the library system, a stateless session is created from the RuleBase and the student's profile is asserted as the fact, then every book that the student can borrow will fire its book rule and you get the complete list of books that the students can borrow in the global result list.

一些假设:图书馆将处理数百万本书;我不认为图书规则过于复杂,平均每条规则最多3个简单的字段限制;系统需要处理的学生数量在100K范围内,因此负载相当重。我的问题是:如果加载了一百万本图书规则,Drools会占用多少内存?所有这些百万条规则的解雇速度有多快?如果Drools是合适的,我想听听一些有经验的用户设计这样一个系统的最佳实践。谢谢。

A few assumptions: the library will handle millions of books; I don't expect the book rule be too complicated, 3 simple field constraints for each rule on average at the most; the number of students that the system needs to handle is in the range of 100K, so the load is fairly heavy. My questions are: how much memory will Drools take if loaded with a million book rules? How fast will it be for all those million rules to fire? If Drools is the right fit, I'd like to hear some best practices in designing such a system from you experienced users. Thanks.

推荐答案

首先,不要为每本书制定规则。制定限制规则—定义的限制比书籍少得多。这将对运行时间和内存使用量产生巨大影响。

First, Don't make rules for every book. Make rules on the restrictions—there are a lot fewer restrictions defined than books. This will make a huge impact on the running time and memory usage.

通过规则引擎运行大量书籍将会非常昂贵。特别是因为您不会向用户显示所有结果:每页只有10-50。想到的一个想法是使用规则引擎来构建一组查询条件。 (我实际上不会这样做—见下文。)

Running a ton of books through the rule engine is going to be expensive. Especially since you won't show all the results to the user: only 10-50 per page. One idea that comes to mind is to use the rule engine to build a set of query criteria. (I wouldn't actually do this—see below.)

以下是我的想法:

rule "Only two books for networking"
when
  Student($checkedOutBooks : checkedOutBooks),
  Book(subjects contains "networking", $book1 : id) from $checkedOutBooks,
  Book(subjects contains "networking", 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本书来运行规则。这将是非常活泼的。以上规则将成为:

This is how I would have changed the problem: Not showing the books to the user is a poor experience. A user may want to peruse the books to see which books to get next time. Show the books, but disallow the checkout of restricted books. This way, you only have 1-50 books to run through the rules at a time per user. This will be pretty zippy. The above rules would become:

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),
  Book(subjects contains "networking", $book1 : id) from $checkedOutBooks,
  Book(subjects contains "networking", 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

我使用activation-group确保只触发一条规则,并确保按照我希望的顺序解雇他们。

Where I am using activation-group to make sure only one rule is fired, and salience to make sure they are fired in the order I want them to be.

最后,保持规则缓存。 Drools允许—并建议—您只将规则加载到知识库中一次,然后从中创建会话。知识库很昂贵,会议很便宜。

Finally, keep the rules cached. Drools allows—and suggests that—you load the rules only once into a knowledge base and then create sessions from that. Knowledge bases are expensive, sessions are cheap.

这篇关于我应该在这种情况下使用Drools吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆