How to sum an array of doubles with ignite data grid / sql?

我怕爱的太早我们不能终老 提交于 2019-12-24 23:22:36

问题


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

回答1:


I see two possible solutions:

  1. Add valuesSum field to MyFact class and calculate it each time values are updated. You can then query this new field directly instead of calculating the array sum each time on the fly.
  2. Use custom SQL functions. The function should be implemented as a static method in a public class and annotated with @QuerySqlFunction annotation. For example:

    public class SqlFunctions {
        @QuerySqlFunction
        public static double arraySum(double[] values) {
            double sum = 0.0;
    
            for (double value : values)
                sum += value;
    
            return sum;
        }
    }
    

    This class has to be provided in the cache configuration:

    cacheCfg.setSqlFunctionClasses(SqlFunctions.class);
    

    You can then run the query like this:

    SELECT SUM(arraySum(values)) FROM ...
    


来源:https://stackoverflow.com/questions/33097103/how-to-sum-an-array-of-doubles-with-ignite-data-grid-sql

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!