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

Hoss Man commented on SOLR-6575:
--------------------------------

I started writting this as a side comment in LUCENE-5325, before i remembered 
this issue already existed - so i'm posting it here and then i'll cross link...

----

Currently...

* ValueSource (via FunctionValues) expose various type specific accessors 
(boolVal, byteVal, doubleVal, floatVal, strVal, etc...) which can be used by 
callers who care about recieving a specific type -- and in which case the 
ValueSource is expected to "do it's best" to return whatever info it models as 
best it can in that type (typically a simple cast). 
* in practice, almost every "ValueSource wrapper" i can think of basically 
ignores the "requested type" when it's FunctionValues are used, and typically 
just uses doubleVal from the wrapped ValueSource/FunctionValues, and then does 
i's own simple cast. (see DualFloatFunction)
* one special case FunctionValues method is "objectVal" in which case the 
FunctionValues/ValueSource gets to make it's own decision about the type of 
object to "pass back" based on what makes the most sense given the source of 
the underlying ValueSource.  (ex: the DocValues type for fields, int for 
NumDocsValueSource, etc..)

Ideally...

* there should be a way to pass the "native typing" of a ValueSource *up* the 
stack, and a way to pass "type preference" down the stack.
* If you wrap a "math function" around 2 arbitrary ValueSources, but you don't 
have a preference about the specific type of the results (ex: a solr user has 
asked for {{product(fieldA,fieldB)}} -- or someone has created a similar 
looking Expression object in the java API) the resulting math operations done 
at the FunctionValues level should look at the "native typing" nformation 
"passed up" from the wrapped ValueSources to decide what data types to use, and 
what to return by default from things like the objectVal method, and what 
"native typing" to in turn pass up to it's own caller
** example: if you wrap 2 IntDocValues field ValueSource in a 
MathMultiplyValueSource maybe the "native result" should be a ValueSource that 
defaults to reutrning LongValues 
* If callers want to force the result to be an explict type - they should still 
be able to do that -- either themselves, or based on the choice of method they 
call (ie: the current FunctionValues methods like intVal, floatVal, etc...) w/o 
that preference automatically propogating down
** example: calling floatVal on a MathMultiplyValueSource that wraps 2 ints 
should be akin to: {{long result = intval1 * intval2; return (float) result;}} 
not {{return ((float)intval1) * ((float)intval2)}}
* we should have ValueSource wrappers that can act as "numeric casts" for folks 
who explicitly want to inject a type preference at arbitrary places in the 
hierarchy.
** example: if you prefer to use floating point multiplication on two 
ValueSources, regardless of what "native type" of those ValueSources are, you 
can wrap each of them in a "CastAsFloatValueSource" and then wrap all of those 
in your MathMultiplyValueSource.

----

There's probably a great way to accomplish much of this very naturally if we 
start moving towards a more type save ValueSource API utilizing generics better 
(allthough i'm not really sure how it we want to keep optimizing for primitive 
types like int/float/long/double instead Integer/Float/Long/Double) but as a 
straw man to try and try and clarify what i'm talking about...

Imagine adding the following to the existing ValueSource APIs..

* imagine if we add a {{Class getNativeClassValue()}} method to ValueSource, 
documented as always returning the same Class as you would get from any call to 
{{FunctionValues.objectVal(int).getClass()}} when using this ValueSource 
directly
* for Math based wrapper ValueSources, the type info from the 
getNativeClassValue() methods of the ValueSources they wrap sould be used to 
decide what FunctionValues impls to return (ie: MathMultiplyValueSource could 
do check the getNativeClassValue() of each VS it wrapped to find the least 
common denominator in the types to decide when to use something like 
MultiplyLongValueSource, or MultipleDoubleValueSource)
* new classes like CastFloatValueSource classes would be ValueSource wrappers 
that completely ignore the getNativeClassValue() of the VS they wrap. They 
would instead implement getNativeClassValue to return a constant Class (ex: 
Float), and would use a FunctionValues impl whose objectVal (and other methods) 
would just call the method that matches the cast they are suppose to do on the 
class they wrap -- ie: {code}Object objectVal(int doc) { return new 
Float(floatVal(doc)); }
int intVal(int doc) { return (int) floatVal(int doc); }
float floatVal(int doc) { return inner.floatVal(int doc); }
...{code}


> ValueSources/FunctionValues should be able to (dynamically) indicate their 
> prefered data type (propogating up)
> --------------------------------------------------------------------------------------------------------------
>
>                 Key: SOLR-6575
>                 URL: https://issues.apache.org/jira/browse/SOLR-6575
>             Project: Solr
>          Issue Type: Improvement
>            Reporter: Hoss Man
>
> Something i've been thinking about for a while, but SOLR-6562 recently goaded 
> me into opening a jira for...
> The ValueSource/FunctionValues API is designed to work with different levels 
> of math precision (int, long, float, double, date, etc...) and the 
> FunctionValues.objectVal() method provides a generic way to fetch an 
> arbitrary type from any FunctionValues instance -- which can be in the 
> "preferred" type for a given ValueSource can be retrieved (ie: an "Integer" 
> if the ValueSource corrisponds to the DocValues of an int field).
> But for ValueSources thta wrap other value sources (ie: implementing math 
> functions like "sum" or "product" there is no easy way at runtime to know 
> which of the underlying methods on the FunctionValues is the "best" one to 
> call.  It would be helpful if FunctionValues or ValueSource had some type of 
> method on it (ie: "canonicalDataType()" that could return some enumeration 
> value inidacting which of the low level various methods (intValue(docid), 
> floatValue(docid), etc...) were best suited for the data it represents.
> Straw man idea...
> For the lowest level ValueTypes coming from DocValues, these methods could 
> return a constant -- but for things like "SumValueSource" 
> "canonicalDataType()" could be recursive -- returning the least common 
> denominator of the ValueSources it wraps. the corrisponding intValue() and 
> floatValue() methods in that class could then cast appopriately.  
> So even if you have SumValueSource wrapped arround several 
> IntDocValuesSource, SumValueSource.canonicalDataType() would return "INT" and 
> if you called SumValueSource's FunctionValues.intValue(docid) it would add up 
> the results of the intValues() methods on all of the wrapped FunctionValues 
> -- but floatValues(docid) would/could still add up the results of the 
> floatValue(docid) results from all of the wrapped FunctionValues (for people 
> who want to coerce float based math -- ie: SOLR-6574)



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to