How to take unique of a list in a DMN? - dmn

I want to take unique of all the elements in a input list to a decision.
For that I am trying to utilize the following FEEL functions in my DMN decision https://cloud.trisotech.com/help/index.html?dmn_feel_functions.htm, but it seems like only the following list of functions are available https://documentation.signavio.com/suite/en-us/Content/process-manager/userguide/dmn/use-literal-expressions.htm.
Does anyone have any idea where i can use the above functions in my DMN. I am trying to write FEEL in 'Expression' tab of my decision.

DMN specification provides a built-in List function to select distinct elements in a feel:list, it's called distinct values().
Example:
distinct values([1,2,3,2,1]) = [1,2,3]
as taken from the DMN specification.
You can use this in any literal expression for instance, or everywhere a FEEL expression is allowed.
Example:
This model, once executed, would result in:
{
My decision : [1,2,3]
}

Related

Handling null when returning through Business Knowledge model in DMN

I am trying to make some Business rules using DMN on kie Server.
There I have structure data object and its list which is my input. I am using rule to validate my structure list and get only those who passes my condition.
I am using BusinessKnowledgeModel which has actual condition for each object and I have decision logic which iterated through my list and calls the BusinessKnowledgeModel function.
Decision Iterator Feel language code:
for inputParam in InputList return BusinessKnowledgeModel(inputParam)
In the BusinessKnowledgeMode, I have my function which consists of decision table that checks my condition through Feels expression.
Instead of getting null as otput from function, I just want to skip it.
My efforts:
I did try to explore trying to find various approaches; like finding if continue keyword can be used in for loop. Even tried adding constraint on Data objects, but not null constraint can't be added on Structures.
There is no equivalent of continue; operator which is typical in procedural languages as FEEL is an expression language. The closes analogy you can draw if you are familiar with say, Java, is that you need something equivalent of what you could do with the JDK Stream, e.g.: filtering in this case sounds appropriate.
It is likely you can achieve what you need by having your expression filtered:
(for inputParam in InputList return BusinessKnowledgeModel(inputParam))[item!=null]
Demonstration
In this example DMN model I have inputList as a list of numbers, and bkm() is a function returning the same number if it's divisible by 2, otherwise null:
if (modulo(p1, 2) = 0) then p1 else null
The Decision-1 node:
is filtering from the returned list of the for, only the numeric element, as you can see input list size is 10 element, Decision-1 list size is only 5 element, filtered out of the nulls
The complete example:
please notice the output column shows the list elements with indexing,
element index 0 is the value 2,
element index 1 is the value 4,
etc.

neo4j fulltext index search with special charcters

We are using neo4j version 4.1.1,
and we have a graph that represents a structure of objects.
we support translation using nodes for translation and the connection between an object and a translation node is the object name and description.
for example:
(n:object)-[r:Translation]-(:ru)
means that on relationship r is the name and description of object n in russian.
In order to search by name and description we implemented a fullText index like that:
CALL db.index.fulltext.createRelationshipIndex("TranslationRelationshipIndex",["Translation"],["Name","Description"], { eventually_consistent: "true" })
We also support search for items in order to do it we are using the index to query and we have names like "UFO41.SI01V03":
CALL db.index.fulltext.queryRelationships('TranslationRelationshipIndex', '*FO41.SI0*') YIELD relationship, scoreĀ 
but for names as shown above([0-9.*]) no results are returned
while results are returned for name like "ab.or"
Is there any one who knows how to make it work? I've tried all 46 analyzers available.
I know we can solve it just using match()-[r]-() where r.Name contains "<string>"
but we prefer a more efficient index-using solution to this problem.
stay safe!
and thanks in advance.
p.s if needed I can supply a few lines to recreate it locally just ask.
The analyzer will probably recognise words like ab.or differently than ab.or123 and consider them a single token in the first case and two tokens in the second case.
There is no analyzer that will really fit your needs except than creating your own.
You can however replace the . in your query with a simple AND, for eg :
CALL db.index.fulltext.queryNodes('Test', replace("*FO41.SI0*", ".", " AND "))
Will return you the results you're looking at.
Resources for creating your own analyser :
https://graphaware.com/neo4j/2019/09/06/custom-fulltext-analyzer.html
https://neo4j.com/docs/java-reference/current/extending-neo4j/full-text-analyzer-provider/

Custom function to calculate on all events in an Esper window

I am wondering what is the best or most idiomatic way to expose all events in a window to a custom function. The following example is constructed following the stock price style examples used in the Esper online documentation.
Suppose we have the following Esper query:
select avg(price), custom_function(price) from OrderEvent#unique(symbol)
The avg(price) part returns an average of the most recent price for each symbol. Suppose we want custom_function to work in a similar manner, but it needs complex logic - it would want to iterate over every value in the window each time the result is needed (eg outlier detection methods might need such an algorithm).
To be clear, I'm requiring the algorithm look something like:
custom_function(window):
for each event in window:
update calculation
and there is no clever way to update the calculation as events enter or leave the window.
A custom aggregation could achieve this by pushing and popping events to a set, but this becomes problematic when primitive types are used. It also feels wasteful, as presumably esper already has the collection of events in the window so we prefer not to duplicate that.
Esper docs mention many ways to customize things, see this Solution Pattern, for example. Also mentioned is that the 'pull API' can iterate all events in a window.
What approaches are considered best to solve this type of problem?
For access to all events at the same time use window(*) or prevwindow(*).
select MyLibrary.computeSomething(window(*)) from ...
The computeSomething is a public static method of class MyLibrary (or define a UDF).
For access to individual event-at-a-time you could use an enumeration method. The aggregate-method has an initial value and accumulator lambda. There is an extension API to extend the existing enumeration methods that you could also use.
select window(*).aggregate(..., (value, eventitem) => ...) from ...
link to window(*) doc and
link to enum method aggregate doc and
link to enum method extension api doc

Is there a method to splt a Map based on the FIRST node to satisfy a predicate?

There is a function called Map.partition that splits the map into 2 maps with one containing ALL elements that satisfy the predicate. The predicate takes a key and a value as arguments and examines each element of the map to determine which result map it belongs to.
My requirement is a special case of this. I have a map and I want to split into 2 maps based on whether or not the key is greater than or less than some value.
This would be much more efficient as you only have to search the tree until the output of the predicate changes. The current implementation would be O(n) and what I am looking for would be O(log(n)). This should be straight forward for a custom tree implementation but I would prefer to use the built in collections if I can, before I roll my own.
The documentation for the F# Maps can be found in the following link: https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/collections.map-module-%5Bfsharp%5D
Altough the operation you want to implement could be implemented in O(log(n)), it is not implemented in this module. The best option would be to use partition (would be O(n), as you said) or implement your own version of Map. You could also search for some code in github which implements a Red-Black Tree and include your own custom method for this operation.
Short Answer: No, there is not a method to split a Map based on the first node to satisfy a predicate.
EDIT: this -> the

Properties aren't ordered alphabetically

I noticed that the ORDER BY clause orders text according to ASCII order, not alphabetically, like, for example, MySQL does.
In other words, this is how Neo4J would order properties:
Apple
Carrot
banana
And MySQL would order them like this:
Apple
banana
Carrot
What is the best way to get Neo4J to sort alphabetically? One way is to use upper (or lower) like this:
MATCH (e) RETURN e.name ORDER BY upper(e.name) ASC;
Another idea is to create a new property, nameSort, which is the same as the name property, but in upper (or lower) case.
Any other ways to do it? I would prefer to do something simple, like the Cypher modification above, rather than creating a new property, but I don't know what the performance implications are.
Neo4j performs lexicographic string ordering, which is what you're seeing. This is documented here. To achieve case-insensitive ordering, you'd need to implement this on your own (such as your suggestion for converting the case either during the query or when storing the property value).

Resources