[ 
https://issues.apache.org/jira/browse/SOLR-9916?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15855876#comment-15855876
 ] 

Dennis Gove commented on SOLR-9916:
-----------------------------------

I've decided to go in a slightly different direction with this. After 
refamilarizing myself with StreamOperations, it became clear that operations 
are meant to modify tuples. For example, the ReplaceOperation replaces some 
field value with some other value via the {code} void operate(Tuple){code} 
function. Newer operations like the BooleanOperation extends that with an 
evaluate() function, but I find it's not quite as clear as it could be. 

Bringing this back to the problem we want to solve: we want to evaluate some 
value based on a tuple. This isn't meant to modify a tuple but instead to 
calculate new values from other values that exist within tuple. This is true 
whether we are adding, multiplying, determining equality, greater than, or 
choosing with an if/else. We are evaluating, but not modifying, the tuple.

To solve this problem, I'm introducing a new set of classes called 
StreamEvaluators. StreamEvaluators follow the same functional expression 
structure as everything else within the streaming sphere and define the 
function {code}public Object evaluate(Tuple){code}. The object returned from 
this function is the result of the evaluation against the tuple. For example, 
the result returned for the expresssion {code}add(a,b){code} is the result of 
field a added to field b. The datatype of the returned result is determined by 
the evaluator and the source field types. For example, {code}add(a,b){code} 
could reasonably return a Number, either Long or Double, while 
{code}eq(a,b){code} could reasonably return a Boolean, while 
{code}if(eq(a,b),c,d){code} could reasonably return any type.

StreamEvaluators come in two basic flavors - those that can contain other 
evaluators and those that can't.
{code}
add(a,b) // field a + field b
sub(add(a,b),c) // (a + b) - c
mult(if(gt("a",b),a,b),c) // if field a > field b then a * c else b * c
if(eq(a,b),val(34),c) // if a == b then value 34 else c
if(eq(a,b),val(foo),c) // if a == b then value "foo" else c
if(eq(a,null),b,c) // if a is null then b else c
{code}

There are a couple pieces of note in here.

* null is a special case and will be treated as a standard null value
* A ValueEvaluator {code}val(<string>), val(<number>), val(<boolean>){code} 
will evaluate to the raw value contained within
** This allows us to easily distinguish between field names and raw string 
values.
* Within any other evaluator, a string, quoted or not, will be considered a 
field name

As a result of this, the class structure is turning into this.

{code}
StreamEvaluator
  ComplexEvaluator // evaluators allowing other StreamEvaluators as parameters 
(looking for better class name)
    NumberEvaluator // evaluators resulting in a Number return value
      AbsoluteValueEvaluator // abs(a)
      AddEvaluator // add(a,b,...,z)
      DivideEvaluator // div(a,b)
      MultiplyEvaluator // mult(a,b,...,z)
      SubtractEvaluator // sub(a,b)
    BooleanEvaluator // evaluators resulting in a Boolean return value
      AndEvaluator // and(a,b,...,z) == true iff all all true
      EqualsEvaluator // eq(a,b,...,z) == true iff all are equal
      GreaterThanEqualToEvaluator
      GreaterThanEvaluator
      LessThanEqualToEvaluator
      LessThanEvaluator
      OrEvaluator
    ConditionalEvaluator // evaluators performing a conditional and returning 
an Object based on the result
      IfThenElseEvaluator
  SimpleEvaluator // evaluators not allowing other StreamEvaluators as 
parameters (looking for a better class name)
    ValueEvaluator // return the raw value as-is
    FieldEvaluator // return the value of the field - not something that needs 
to be expressed in the expression
{code}

StreamEvaluators will become a type of parameter supported by the SelectStream 
and executed *after* the execution of operations in that select clause. The 
result of the evaluation will be put into the tuple under the 'as' field name.

{code}select(...,add(a,b) as aPlusb){code}

> Add arithmetic operations to the SelectStream
> ---------------------------------------------
>
>                 Key: SOLR-9916
>                 URL: https://issues.apache.org/jira/browse/SOLR-9916
>             Project: Solr
>          Issue Type: New Feature
>      Security Level: Public(Default Security Level. Issues are Public) 
>            Reporter: Joel Bernstein
>
> One of the things that will be needed as the SQL implementation matures is 
> the ability to do arithmetic operations. For example:
> select (a+b) from x;
> select sum(a)+sum(b) from x;
> We will need to support arithmetic operations within the Streaming API to 
> support these types of operations.
> It looks like adding arithmetic operations to the SelectStream is the best 
> place to add this functionality.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@lucene.apache.org
For additional commands, e-mail: dev-h...@lucene.apache.org

Reply via email to