Drools: How to get all elements not in map - java

I'm using JBoss Drools 5.5.0 rules.
I have an ArrayList<ElementDetail>, and Map<String, ElementDetail>, and I need to do print out all the ElementDetail in ArrayList but not in Map.
class ElementDetail {
private String name;
...
}
ElementDetail class has a name variable which is identified as the Map key.
So far this is what I tried, but it gives no matches:
...
when
eleList : List()
$eleDetail : ElementDetail() from eleList
$map: Map(myMap.keySet contains $eleDetail.getName())
...
I was able to find similar posts for matching elements in a collection, but it does not get the unmatched elements for a map:
Drools and Maps
drools rule get value from a map
to check if an Object is present in List in Drools

Well, you'll have to use the negated form of contains, and myMap is not bound.
$eleList : List()
$eleDetail : ElementDetail( $name: name ) from $eleList
$map: Map( keySet not contains $name )

Related

jOOQ select with map type values

There is a table that has map type column, and the map column type would be like below
Map<String, CustomClass.class>
and CustomClass is like below
Class CustomClass {
String name;
String attr;
}
I would like to select record that match 'keyword' contain in map column's values (no matter what key is). I need something like below. Is there any way that I can use?
JooqQuery jooqQuery = (SelectJoinStep<?> step) -> {
step.where(MANAGERS.NAME_DESC_I18N_MAP.contains(
Map<"ANY KEY", keyword in CustomClass.name> // need help here
));
You can use LIKE as a quantified comparison predicate in jOOQ. If it's not supported natively by your RDBMS, jOOQ will emulate it for you. Try this:
MANAGERS.NAME_DESC_I18N_MAP.like(any(
map.values().stream().map(cc -> "%" + cc.name + "%").toArray(String[]::new)
))
You can't use contains() in this way yet, but I guess that's OK.
See also this blog post about using LIKE as a quantified comparison predicate.

Filter Object list with map key value , replace the Map value

I have a List of Objects
List<Person> personLst = [{"person:" {personName:AASH_01 , country :AUS, state :ADL, zip :null },
{personName:AASH_01 , country :AUS, state :MLB, zip :null}}]
and Map holds a key value and based on this need to apply the filter for the list.
Map<String, String> lstMap = new HashMap<>();
lstMap.put("ADL","12345")
Apply Filter Condition:
If the personLst.contains(ADL) this is a map key filter it and replace the zip with map value(12345).
Tried different stackoverflow question , did not help much on .
Just to be sure,
List<Person> personLst = [{"person:" {personName:AASH_01 , country :AUS, state :ADL, zip :null },{personName:AASH_01 , country :AUS, state :MLB, zip :null}}]
really refers to a list of valid java objects, right? Because in the current state those would be valid JavaScript Objects, but not valid Java objects.
Also, should a List<Person> really be called with personLst.contains(String)?
So, assuming these are valid Java objects with the correct getters and setters, and the correct method is intended, you should be able to use
personLst.forEach(p -> {
if(lstMap.containsKey(p.getState()))
p.setZip(lstMap.get(p.getState()));
});

Hazelcast PredicateBuilder with nested key

I am trying to add an entrylistener to my hazelcast map using a predicate to filter the entries.
The method I am calling is:
String addEntryListener(MapListener listener,
Predicate<K,V> predicate,
boolean includeValue)
I am trying to build a predicate to filter by my key. My keys are of type HazelKey which have the fields:
KeyOne keyOne;
KeyTwo keyTwo;
KeyThree keyThree;
Then these three Keys have the field:
String code
Therefore i am trying to do something along the lines of:
PredicateBuilder predicate = EntryObject.key().get("keyOne").get("code").equal("1234");
to build a predicate to filter all the entries with the keyOne value 1234.
However once the listener has been added, the entries get updated, hazelcast throws the error:
Caused by: com.hazelcast.query.QueryException: java.lang.IllegalArgumentException: There is no suitable accessor for 'code' on class 'class com.sun.proxy.$Proxy45'
I believe this is because the predicateBuilder is just ignoring the top level 'KeyOne' paramater and just using 'code' so my question is: How do I do this multilevel predicatebuilding?
Thanks in advance.
I am not too familiar with PredicateBuilder, but I believe this should work for you:
import static com.hazelcast.query.Predicates.equal;
[...]
Predicate p = equal("keyOne.code", 1234);

Map attributes not updated properly in Dynamo. New field is added instead.

I am using the AWS Java SDK for communicating with DynamoDB. I am trying to do a table update of some properties stored in a map.
Before the update, I have an object that looks like this:
{
"myMap": {
"innerMap": {}
},
"hashKeyName": "hashKeyValue"
}
My code looks like this:
Table myTable = ...;
myTable.updateItem("hashKeyName", "hashKeyValue",
new AttributeUpdate("myMap.innerMap.myKey").addNumeric(100));
After this update, my Dynamo object looks like this (notice that the map is still empty):
{
"myMap": {
"innerMap": {}
},
"myMap.innerMap.myKey": 100,
"hashKeyName": "hashKeyValue"
}
Why was myMap.innerMap.myKey added as a separate field instead of being correctly set in the map?
The reason for this is because using AttributeUpdate is considered a legacy operation and the usage of map keys as attribute names is not supported. The correct usage to use an update expression:
myTable.updateItem("hashKeyName", "hashKeyValue",
"ADD myMap.innerMap.myKey :val", null /* NameMap, see comment */,
new ValueMap().withNumeric(":val", 100));
Notice that there is no name map in the above expression. One might be tempted to do use ADD #name :val as an update expression and then provide a name map for #name => myMap.innerMap.myKey. In this case, these expressions are not equivalent. When a . appears in the raw expression, it is treated as a path separator. When . appears in a NameMap value, it is not considered a path separator.

how can I get dynamic property in drools

I have a XML file containing metadata like a field's maximum length. I have to use drools to build rules to validate this metadata against a list of facts. I don't want to hardcode the name of each field that may or may not be specified in the XML.
I tried to do this :
when
$metadata: Metadata(maxLength != null);
$obj: Object(eval($metadata.getFieldName()).length > $metadata.maxLength);
then
// TODO
end
It does not work and I get the following error :
java.lang.IllegalStateException: Errors while building rules : Unable
to Analyse Expression $metadata.getFieldName() > $metadata.maxLength:
[Error: Comparison operation requires compatible types. Found class
java.lang.String and class java.lang.Integer] [Near : {...
$metadata.getFieldName() > $metadata.maxLength ....}]
Is it possible to dynamically get a field name and compare its maximum length? Will I have to create a java object to accomplish this?
Thank you
You talk of XML and metadata. Can you distinguish all entities? For example, if it is about orders, can you extract each order, and attributes of each order?
I solved a similar problem with using maps to store each attribute.
public class Order{
private int id;
private Map<String, Integer> num_attribute_map = new HashMap<String, Integer>();
public Map getNumAttributeMap(){
return this.num_attribute_map;
}
If an order has customer_satisfaction = 5,
order_obj.getNumAttributeMap().put("customer_satisfaction" , 5);
And thus you have created Orders with their attributes stored in the numAttributeMap.
For implementing a rule on an Order
$ord : Order(
getNumAttributeMap[$attribute] >= $value
)
where $attribute would be "customer_satisfaction", of course. The [] notation is used to access elements of a list, given index or values of a map, given the key.
Hope you "get" the concepts of maps. Also, do look up Drools language support for list and map access.
I have also implemented maps of lists of strings to perform an "is in" operation, in addition to maps of integers that do comparison operations. Please refer https://stackoverflow.com/a/9241089/604511 too
Finally, I have decided to generate my drools file dynamically from my XML using rule templates.

Categories

Resources