How to sum an array of doubles with ignite data grid / sql?
Given: 1 dimension table MyDimension and 1 fact table MyFact. Join them, group by a few dimensions ** and sum the fact associated with it. Now consider the fact table to sum, doesn't contain a single double value, but an array of doubles. And the sum to retrieve, is an array representing the sum of all the arrays.
As an example words: Assume "All the arrays are":
array 1: double[] { 1.0, 2.0, 3.0, 4.0, 5.0 }
array 2: double[] { 2.0, 3.0, 4.0, 5.0, 6.0 }
array 3: double[] { 3.0, 4.0, 5.0, 6.0, 7.0 }
then the "array representing the sum of all the arrays" would be: double[] { 6.0, 9.0, 12.0, 15.0, 18.0 }
I've looked into @QuerySqlFunction, but couldn't find any example that could help me.
This doesn't HAVE to be sql. Any way to get a sum of arrays out of my cache would be great.
thanks,
Johan
MyFact
package com.hsbc.rsl.babarpoc.ignite.starschema;
import org.apache.ignite.cache.query.annotations.QuerySqlField;
public class MyFact {
/** Primary key. */
@QuerySqlField(index = true)
private long uid;
@QuerySqlField(index = true)
private long dimensionUid;
@QuerySqlField
private double values[];
public MyFact(long uid, long dimensionUid, double values[]) {
this.uid = uid;
this.dimensionUid = dimensionUid;
this.values = values;
}
public long getUid() {
return uid;
}
public void setUid(long uid) {
this.uid = uid;
}
public long getDimensionUid() {
return dimensionUid;
}
public void setDimensionUid(long dimensionUid) {
this.dimensionUid = dimensionUid;
}
public double[] getValues() {
return values;
}
public void setValues(double[] values) {
this.values = values;
}
}
MyDimension
import org.apache.ignite.cache.query.annotations.QuerySqlField;
public class MyDimension {
@QuerySqlField(index = true)
private long uid;
@QuerySqlField
private String groupBy1;
@QuerySqlField
private String groupBy2;
public MyDimension(String groupBy1, String groupBy2) {
this.groupBy1 = groupBy1;
this.groupBy2 = groupBy2;
}
public long getUid() {
return uid;
}
public void setUid(long uid) {
this.uid = uid;
}
public String getGroupBy1() {
return groupBy1;
}
public void setGroupBy1(String groupBy1) {
this.groupBy1 = groupBy1;
}
public String getGroupBy2() {
return groupBy2;
}
public void setGroupBy2(String groupBy2) {
this.groupBy2 = groupBy2;
}
}
The query (the one that doesn't work)
I add an example sql below, which will give the sum of 1 value, ie it will not work for the array: it would generate an error.
SELECT
MyDimension.groupBy1,
MyDimension.groupBy2,
SUM(MyFact.values)
FROM
"dimensionCacheName".DimDimension,
"factCacheName".FactResult
WHERE
MyDimension.uid=MyFact.dimensionUid
GROUP BY
MyDimension.groupBy1,
MyDimension.groupBy2
I see two possible solutions:
valuesSum
field toMyFact
class and calculate it each timevalues
are updated. You can then query this new field directly instead of calculating the array sum each time on the fly.Use custom SQL functions. The function should be implemented as a static method in a public class and annotated with
@QuerySqlFunction
annotation. For example:This class has to be provided in the cache configuration:
You can then run the query like this: