java - 使用流口水验证具有嵌套地图的事实
问题描述
我有一个类Fact
是扩展java.util.HashMap
类。我将此类的对象作为事实传递给流口水。现在一个 fact 的实例看起来像这样(Map<String, Object>):
{
"key1": "value"
"attributes": [{"name": "name1", "value": "value1"},{"name": "name2", "value": "value2"},{"name": "name3", "value": "value3"}...]
"locks": [{"type": "type1", "value": "value1", "attributes": {"key_a1": "val_a1""key_a2": "val_a2"...}}]
}
在此映射中的根级别条目上运行验证是直截了当的,例如在key1
.
现在,我想在attributes
和上运行一些验证locks
。对于属性,我想确保这张地图中存在所有需要的属性,并且它们的对应值是正确的。所以我在 when 块中这样做:
fact: Fact(this["key1"] != null && this.containsKey("attributes"));
attributesEntries: Entry(key == "attributes") from fact.entrySet();
attributesMaps: LinkedHashMap() from attributesEntries;
事实上,HashMap
属性是类型的(还为其值添加了ArrayList<LinkedHashMap<String, String>>
一个键,其值仅是键名的值)。
锁是类型
锁具有 Map<String, String> 类型的属性id
LinkedHashMap
ArrayList<LinkedHashMap<String, Object>>
但它不工作。当我评估attributesEntries
它时ArrayList<LinkedHashMap>
,它具有所有预期值,但attributesMaps
为空。我也尝试过像这样的过滤器,LinkedHashMap(key == 'key1', value == 'val1')
但这也没有用。尝试寻找解决方案,但没有一种可用于这种结构。无论有什么可用的,我都试图扩展,但没有奏效。这有可能实现吗?如果可以,如何实现?此外,一旦我能够从Map
.
我是 drools 的新手,我们正在使用 5.4.0.Final 版本的 drools。
另外,我如何使用嵌套Map
在locks
.
解决方案
我曾经在一个项目中遇到过不幸,我们犯了同样的错误并让我们的类扩展了 HashMap。(公平警告:HashMap 不能很好地序列化,因此您将使用大量额外的内存。)
我将假设有关您的模型的几件事,因为您忽略了共享类定义本身。
但我将根据您的示例 JSON 假设以下内容:
- 您添加了一个带有键“key1”的字符串值(“value”)
- 您添加了一个带有“锁”键的
List<Map<String, ?>>
值(可能是 a )List<Fact>
- 您添加了一个带有键“attributes”的
List<Map<String, ?>>
值(可能是 a )List<Fact>
HashMap 的get(key)
方法会返回一个对象值;你已经注意到了特殊的this[ key ]
语法。
从您的部分规则尝试来看,您要尝试做什么并不完全清楚。我认为您正在尝试获取List<Map<String, ?>>
保存在“属性”键下的地图中的内容。
rule "Do something with the attributes"
when
$fact: Fact( this["key1"] != null,
$attr: this["attributes"] != null )
then
System.out.println("Found " + $attr.size() + " attributes");
end
this["attributes"]
返回与键属性关联的值。在这种情况下,它是一个列表或任何你塞进去的东西。如果该键不存在,则 null 检查会处理该问题。
您还询问了如何在其中一个列表中使用子地图进行操作。假设想要对具有"name": "name1"
...的属性做某事
rule "Do something with the 'name = name1' attribute"
when
$fact: Fact( this["key1"] != null,
$attributes: this["attributes"] != null )
$nameAttr: Map( this["name"] == "name1" ) from $attributes
then
// do something with $nameAttr
end
当然,这种模式会重复。假设您已将另一个推List<Map<String, ?>>
入属性映射:
rule "Do something with a child of 'name' attribute"
when
$fact: Fact( this["key1"] != null,
$attributes: this["attributes"] != null )
$nameAttr: Map( this["name"] == "name1",
$attrKids: this["children"] != null ) from $attributes
$childNameAttr: Map( this["name"] == "child1" ) from $attrKids
then
// etc.
end
我强烈建议重新考虑您的对象模型不是基于地图的。在我工作的公司,我们所有的项目都是基于嵌套的基于 Map 的模型构建并运行 Drools 5.0.1,我花费了大量的时间和精力将其中的一部分升级到 Drools 7 和只传递数据的适当模型我们需要。它节省了大量资源,最终速度更快。
推荐阅读
- java - Clojure 的正则表达式解析/编译有多聪明?
- php - Magento2:如何以编程方式添加具有多个属性的可配置产品?
- firebase - 如何使搜索不区分大小写
- c# - MVC 将行拆分为列或组
- flutter - 我需要在 Flutter 中发送带有调度的通知
- flutter - widget.routeName 必须是一个以正斜杠 (/) 开头的字符串
- javascript - JavaScript - 为什么我的 API 调用变量返回未定义?
- asp.net-core - 脚本评分功能不得产生负分/查询失败/阶段查询弹性搜索的所有分片失败
- java - 线程“main”java.lang.Error 中的异常:未解决的编译问题:在scanner.scan.main(scan.java:8)
- r - 使用 bsts 包中的函数 bsts() 使用 MCMC 进行贝叶斯时间序列分析