基于apache中的列表字段的订购记录会点燃Sql查询

时间:2018-04-05 18:08:59

标签: ignite

假设我在下面有一个对象Employee,它存储在ignite缓存中。

   Employee{
    int id;
    String name;
    List<Double> marksInorder;//marks for each subject in order
    //hypothetical situation, actual requirement is different
  }

我正在使用SQLQuery从点火缓存中获取记录,并且需要获取最多具有marksInorder的前N个记录。但是ignite不支持列表字段中的orderBy。

http://apache-ignite-users.70518.x6.nabble.com/Ignite-SQL-Queries-on-Lists-fields-sorting-td14129.html#a14305

是否有解决方法。

2 个答案:

答案 0 :(得分:3)

我使用@QuerySqlFunction找出了解决方案。我的自定义SqlFunction正在将列表中的双精度转换为列表中的最大值,最后我按降序对其进行排序。观看输出。这是

public class Student implements Serializable {
    @QuerySqlField(index = true)
    private int Id;
    @QuerySqlField(index = true)
    private String name;

    @QuerySqlField(index = true)
    private List<Double> marks;
    //rest of POJO code

}

public class MySqlFunctions {
    @QuerySqlFunction
    public static double maxOf(List<Double> marksInorder) {
        Collections.sort(marksInorder, Collections.reverseOrder());
        return marksInorder.get(0);
    }
}


public static void main(String[] args) {
        Ignite ignite = Ignition.start("examples/config/example-ignite.xml");
        CacheConfiguration<Integer, Student> config = new CacheConfiguration<>("students");
        config.setIndexedTypes(Integer.class, Student.class);
        config.setSqlFunctionClasses(MySqlFunctions.class);
        IgniteCache<Integer, Student> cache = ignite.getOrCreateCache(config);
        List<Double> marks1 = new ArrayList<>();
        List<Double> marks2 = new ArrayList<>();
        List<Double> marks3 = new ArrayList<>();
        marks1.add(12.3);
        marks1.add(4.3);
        marks2.add(1.3);
        marks2.add(14.3);
        marks3.add(13.3);
        marks3.add(3.3);
        Student s1 = new Student(1, "John", marks1);
        Student s2 = new Student(2, "Dan", marks2);
        Student s3 = new Student(3, "Ron", marks3);
        cache.put(s1.getId(), s1);
        cache.put(s2.getId(), s2);
        cache.put(s3.getId(), s3);
        String sql = "select * from Student order by maxOf(marks) desc";
        SqlQuery<Integer, Student> query = new SqlQuery<>(Student.class, sql);
        List<Student> result = cache.query(query).getAll().stream().map(e -> e.getValue()).collect(Collectors.toList());
        System.out.println("Result : " + result);
    }


Result : [Student [Id=2, name=Dan, marks=[1.3, 14.3]], Student [Id=3, name=Ron, marks=[13.3, 3.3]], Student [Id=1, name=John, marks=[12.3, 4.3]]]

答案 1 :(得分:1)

我认为最简单的解决方法是添加Double maxmark字段并将其配置为编入索引。