Eval (query directive)

From WandoraWiki
(Difference between revisions)
Jump to: navigation, search
m (Examples)
 
(9 intermediate revisions by one user not shown)
Line 3: Line 3:
 
Evaluates a script. The script can do simple modifications to the input value or be arbitrarily complex.
 
Evaluates a script. The script can do simple modifications to the input value or be arbitrarily complex.
  
The script context is initialized with three values.
+
The script context is initialized with some values.
* ''input'' contains the entire input row.
+
* ''input'' contains the entire input row.
* ''context'' contains the query context, you can get the active topic map from it.
+
* ''context'' contains the query context, you can get the active topic map from it.
* ''val'' contains the active value of the input row.
+
* ''val'' contains the active value of the input row.
 +
* ''dir'' contains the ''Eval'' directive itself.
 +
* ''param'' contains the object passed as an additional parameter to the constructor.
  
The value on the last lime of the script is the return value of the script. it can be one of four things:
+
The ''Eval'' directive contained in ''dir'' variable has some useful methods.
 +
 
 +
* ''set(String key,Object value)'' Sets an object in an internal hash map. You can use this to store anything you like. It is cleared between queries. If the same sub-query is executed several times in a query, it will retain its contents between each execution.
 +
* ''get(String key)'' Gets an object from the internal hash map.
 +
* ''empty()'' Returns an empty result iterator.
 +
 
 +
The value on the last line of the script is the return value of the script. it can be one of four things:
  
 
* A ''ResultIterator'' object which is returned as is as the result of the directive. It may be an empty iterator or iterate through any number of rows
 
* A ''ResultIterator'' object which is returned as is as the result of the directive. It may be an empty iterator or iterate through any number of rows
Line 15: Line 23:
 
* Any other object which will be added in the input row with the default column name.
 
* Any other object which will be added in the input row with the default column name.
  
In most cases the last option is sufficient and is by far the easiest to implement.
+
In most cases the last option is sufficient and is by far the easiest to implement. Note that returning null falls under the last case and it will produce a result row with a null value. Easiest way to return nothing, that is zero result rows, is to use the ''empty'' method in the ''dir'' variable. Just doing ''dir.empty()'' creates a new empty ''ResultIterator''.
  
 
== Constructor ==
 
== Constructor ==
  
Eval()
+
Eval(String script)
 +
 
 +
Eval(String script,Object param)
  
 
== Examples ==
 
== Examples ==
Line 26: Line 36:
  
 
  importPackage(org.wandora.query2);
 
  importPackage(org.wandora.query2);
  new Expr("\"BaseName: \"+val")
+
  new Eval("\"BaseName: \"+val")
 
  .from(new BaseName())
 
  .from(new BaseName())
 
  .from(new Instances())
 
  .from(new Instances())
 +
 +
Following example returns instances that have the string "type" in their base name. (Note that you can do this easier with [[Regex (query directive) |Regex]] directive.) Note the use of ''input'' variable to return the input row as is and ''dir.empty()'' to return nothing.
 +
 +
importPackage(org.wandora.query2);
 +
new Eval(
 +
"if(val!=null && val.indexOf(\"type\")!=-1) "+
 +
"  input;"+
 +
"else"+
 +
"  dir.empty();"
 +
).from(
 +
  new BaseName().from(
 +
    new Instances().as("#instance")
 +
  )
 +
)
 +
 +
Next example demonstrates the internal hash map. The eval part returns the previously stored object.
 +
 +
importPackage(org.wandora.query2);
 +
new Eval(
 +
"ret=dir.get(\"old\");"+
 +
"dir.set(\"old\",val);"+
 +
"ret;"
 +
).as("#eval").from(new Instances().as("#instance"))
 +
 +
Another way to store information is using the param object. Here we pass a java script table ''{sum:0}'' to ''Eval'' constructor and then access it in the script using ''param''. Note that it is easier to do the same thing as this query using [[Sum (query directive) |Sum]] directive.
 +
 +
importPackage(org.wandora.query2);
 +
new Last(
 +
  new Eval(
 +
    "param.sum+=parseInt(val);"+
 +
    "param.sum;"
 +
  ,{sum:0}).as("#sum")
 +
  .from(
 +
    new Count(
 +
      new Instances()
 +
    ).from(new Instances())
 +
  )
 +
)
 +
 +
Next example has a much more complex script in the ''Eval'' directive. It selects all players in all associations of the input that do not merge with the input topic (i.e. are not the same topic as input). Then we use ''Unique'' to remove duplicates, count the number of rows and then take average over all topics in the topic map. In the end we get the average number of topics each topic in the topic map is connected to by associations. You can use back-slash character to continue a string (the script itself) to next line.
 +
 +
importPackage(org.wandora.query2)
 +
new Average(
 +
  new Count(
 +
    new Unique(
 +
      new Eval("\
 +
topic=input.getActiveValue();\
 +
as=topic.getAssociations();\
 +
iter=as.iterator();\
 +
ret=new java.util.ArrayList();\
 +
while(iter.hasNext()){\
 +
  a=iter.next();\
 +
  rs=a.getRoles();\
 +
  iter2=rs.iterator();\
 +
  while(iter2.hasNext()){\
 +
    r=iter2.next();\
 +
    p=a.getPlayer(r);\
 +
    if(!topic.mergesWithTopic(p)) ret.add(input.addValue(p));\
 +
  }\
 +
}\
 +
ret;\
 +
      ")
 +
    )
 +
  ).from(new AllTopics().as("#topic"))
 +
)
 +
  
 
[[Category:Query directives]]
 
[[Category:Query directives]]

Latest revision as of 16:11, 29 November 2013

[edit] Description

Evaluates a script. The script can do simple modifications to the input value or be arbitrarily complex.

The script context is initialized with some values.

  • input contains the entire input row.
  • context contains the query context, you can get the active topic map from it.
  • val contains the active value of the input row.
  • dir contains the Eval directive itself.
  • param contains the object passed as an additional parameter to the constructor.

The Eval directive contained in dir variable has some useful methods.

  • set(String key,Object value) Sets an object in an internal hash map. You can use this to store anything you like. It is cleared between queries. If the same sub-query is executed several times in a query, it will retain its contents between each execution.
  • get(String key) Gets an object from the internal hash map.
  • empty() Returns an empty result iterator.

The value on the last line of the script is the return value of the script. it can be one of four things:

  • A ResultIterator object which is returned as is as the result of the directive. It may be an empty iterator or iterate through any number of rows
  • A ResultRow object which will be the single result row of the dirictive.
  • An ArrayList containing ResultRow which will be converted to a ResultIterator iterating through the rows in the list.
  • Any other object which will be added in the input row with the default column name.

In most cases the last option is sufficient and is by far the easiest to implement. Note that returning null falls under the last case and it will produce a result row with a null value. Easiest way to return nothing, that is zero result rows, is to use the empty method in the dir variable. Just doing dir.empty() creates a new empty ResultIterator.

[edit] Constructor

Eval(String script)

Eval(String script,Object param)

[edit] Examples

Following example selects base names of all instances of the input topic and adds the prefix "BaseName: " before each of them.

importPackage(org.wandora.query2);
new Eval("\"BaseName: \"+val")
.from(new BaseName())
.from(new Instances())

Following example returns instances that have the string "type" in their base name. (Note that you can do this easier with Regex directive.) Note the use of input variable to return the input row as is and dir.empty() to return nothing.

importPackage(org.wandora.query2);
new Eval(
"if(val!=null && val.indexOf(\"type\")!=-1) "+
"  input;"+
"else"+
"  dir.empty();"
).from(
  new BaseName().from(
    new Instances().as("#instance")
  )
)

Next example demonstrates the internal hash map. The eval part returns the previously stored object.

importPackage(org.wandora.query2);
new Eval(
"ret=dir.get(\"old\");"+
"dir.set(\"old\",val);"+
"ret;"
).as("#eval").from(new Instances().as("#instance"))

Another way to store information is using the param object. Here we pass a java script table {sum:0} to Eval constructor and then access it in the script using param. Note that it is easier to do the same thing as this query using Sum directive.

importPackage(org.wandora.query2);
new Last(
  new Eval(
    "param.sum+=parseInt(val);"+
    "param.sum;"
  ,{sum:0}).as("#sum")
  .from(
    new Count(
      new Instances()
    ).from(new Instances())
  )
)

Next example has a much more complex script in the Eval directive. It selects all players in all associations of the input that do not merge with the input topic (i.e. are not the same topic as input). Then we use Unique to remove duplicates, count the number of rows and then take average over all topics in the topic map. In the end we get the average number of topics each topic in the topic map is connected to by associations. You can use back-slash character to continue a string (the script itself) to next line.

importPackage(org.wandora.query2)
new Average(
  new Count(
    new Unique(
      new Eval("\
topic=input.getActiveValue();\
as=topic.getAssociations();\
iter=as.iterator();\
ret=new java.util.ArrayList();\
while(iter.hasNext()){\
  a=iter.next();\
  rs=a.getRoles();\
  iter2=rs.iterator();\
  while(iter2.hasNext()){\
    r=iter2.next();\
    p=a.getPlayer(r);\
    if(!topic.mergesWithTopic(p)) ret.add(input.addValue(p));\
  }\
}\
ret;\
      ")
    )
  ).from(new AllTopics().as("#topic"))
)
Personal tools