在这种情况下我应该使用 Drools 吗?

2023-12-25

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

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

一些假设:图书馆将处理数百万册图书;我不希望书上的规则太复杂,平均每条规则最多3个简单的字段约束;系统需要处理的学生数量在100K左右,负载相当大。我的问题是:如果加载一百万本书规则,Drools 会占用多少内存?所有这百万条规则的触发速度有多快?如果 Drools 适合您,我想听听经验丰富的用户设计此类系统的一些最佳实践。谢谢。


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

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

这就是我的想法:

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 本书即可运行规则。这会非常敏捷。上述规则将变为:

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

我使用激活组来确保只触发一条规则,并使用显着性来确保它们按照我希望的顺序触发。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在这种情况下我应该使用 Drools 吗? 的相关文章

随机推荐

  • 合并 MongoDB 聚合中的数组字段

    使用 MongoDB 聚合框架时是否可以合并数组字段 这是我试图解决的一个摘要问题 用于聚合的示例输入文档 Category 1 Messages Msg1 Msg2 Value 1 Category 1 Messages Value 10
  • 使用 UNC 路径的 Windows 8 StorageFile.GetFileFromPathAsync

    有没有人曾经设法使用 Windows 8 应用程序将文件从 unc 目录复制到本地目录 根据这里的官方文档 http msdn microsoft com en us library windows apps hh967755 aspx 可
  • 如何在 C# 中解密由 PHP 中的 mcrypt 加密的加密 MCRYPT_RIJNDAEL_256 值?

    我正在尝试从 Linux 端管理的数据库表中读取 Base64 编码的值 在那里面 表中有一个名为first name 的列 在 Linux 端 我可以通过在 PHP 中使用以下命令轻松解密 data mcrypt decrypt MCRY
  • C++11 - 编译时多态解决方案

    假设我正在编写一个跨平台库 我必须以不同平台有不同行为的方式组织代码 并且这种行为 或定义 是在编译时根据我的库所在的平台选择的正在编译中 在 C 中执行此操作的 通常 方法是用大量的内容污染代码 ifdef当编写方法或类时 方法的问题在于
  • UTF16 十六进制转文本

    我有 UTF 16 十六进制表示形式 例如 0633064406270645 它是阿拉伯语中的 S 我想将其转换为其等效文本 在 PostgreSQL 中有直接的方法可以做到这一点吗 我可以像下面这样转换 UTF 代码点 不幸的是 似乎不支
  • F# 类型提供程序构建非常非常慢

    我正在使用类型提供程序 特别是 sql 实体框架类型提供程序 我正在针对一个包含大量对象的数据库编写测试 并且它是远程的 因此连接有点慢 每次我构建项目都会花费很多时间 需要几分钟才能完成构建 我缺少什么为什么编译器不缓存类型信息 附 使用
  • lxml.etree、element.text 不返回元素的整个文本

    我通过 xpath 废弃了一些 html 然后将其转换为 etree 与此类似的东西 td text1 a link a text2 td 但是当我调用 element text 时 我只得到 text1 它必须在那里 当我在 FireBu
  • laravel 从模型生成数据库

    我正在使用 Laravel 的现有项目 并且该现有项目已经有模型 这里是一个示例
  • DVTCoreSimulatorAdditionsErrorDomain Xcode 10GM

    当我将Xcode更新到Version 10 GM时 构建成功 但模拟器无法工作 有错误 操作无法完成 DVTCoreSimulatorAdditionsErrorDomain 错误 0 run xcrun simctl erase all在
  • 如何在mysql中为不同的字符长度添加前导零?

    您好 我对不同的表有一个查询 并且所有表都有不同的长度 这需要前导零ID 是否可以使用一个查询向任何表添加前导零 假设第一个查询是insert to tbl1 field1 CHAR 3 001 那么下一个查询是insert to tbl2
  • 在 Python 中读取和切片二进制数据文件的最快方法

    我有一个处理脚本 旨在提取 uint16 类型的二进制数据文件 并一次以 6400 块为单位进行各种处理 该代码最初是用 Matlab 编写的 但由于分析代码是用 Python 编写的 因此我们希望通过在 Python 中完成所有操作来简化
  • 在 Python 中将可变长度字符串拆分为变量的最佳方法是什么?

    假设我有一个由可变长度的逗号分隔的整数字符串 分割字符串并将整数存储到变量中的最佳方法是什么 目前 我有以下内容 input sys argv 1 mylist int x for x in input split if len mylis
  • 如何在应用程序设置中存储 int[] 数组

    我正在使用 C Express 2008 创建一个简单的 Windows 窗体应用程序 我是一位经验丰富的 C 开发人员 但我对 C 和 NET 几乎是全新的 我目前正在使用设置设计器和代码存储一些简单的应用程序设置 如下所示 Store
  • Django-Tastypie:如何访问 Bundle 中的 (Http)request 对象?

    我需要访问资源脱水中的 HttpRequest 对象 方法 在文档中 它表明bundle request是一个有效的属性 它是 在 resources html 页面中 当我尝试将其添加到我的代码中时 我得到一个 错误声称 Bundle 对
  • 如何使用 useReducer([state,dispatch]) 和 useContext 避免无用的重新渲染?

    当使用多个 useReducers 时 每个组件都会使用部分状态重新渲染 import React useContext from react import Store from store import setName from acti
  • 在 Swift 中获取 UIBarButtonItem 的框架?

    我怎样才能快速获得 rightbarbuttonItem 的框架 我找到了这个 UIBarButtonItem 如何找到它的框架 https stackoverflow com questions 14318368 uibarbuttoni
  • 使用 tlmgr 搜索所有关键字

    我想知道如何查找所有 TeX Live 关键字 我正在使用 Windows 10 和 TeX Live 2019 我尝试过这个命令tlmgr search list keyword但我没有收到 except 结果 这种语法不再可能了 看着h
  • 在 UML 类图中,什么是边界类、控制类和实体类?

    我现在使用 NetBeans 作为我选择的 IDE 它有一个用于 UML 建模的插件 在类图中 有一些模型元素称为Boundary Class Control Class and Entity Class 然而 我找不到它们的一个好的定义
  • 为什么 PL/SQL 不尊重角色授予的权限?

    执行 PL SQL 块时 授予角色的任何权限都将被忽略 相反 您必须为特定用户提供特定的授权才能运行它 如果我想授予 DBA 访问包 函数或过程的权限 我无法向 DBA 角色授予权限 我必须向 DBA 角色中的每个用户授予授权 如果用户不再
  • 在这种情况下我应该使用 Drools 吗?

    我将使用大学的图书馆系统来解释我的用例 学生在图书馆系统中注册并提供个人资料 性别 年龄 院系 以前完成的课程 当前注册的课程 已借阅的书籍等 图书馆系统中的每本书都会根据学生的资料定义一些借阅规则 例如 计算机算法课本只能由当前注册该班级