Apache Calcite Linq4j学习

Lin4j简介

Linq4j是Apache Calcite项目中的一个模块,它提供了类似于LINQ(Language-Integrated Query)的功能,用于在Java中进行数据查询和操作。Linq4j可以将逻辑查询转换为物理查询,支持对集合进行筛选、映射、分组等操作。

例如,通过Linq4j可以将类似于以下的逻辑查询语句转换为最终的在java集合上的查询操作:

java 复制代码
Enumerable<Employee> employees = ...; 
Enumerable<String> names = employees
    .where(emp -> emp.getSalary() > 50000)
    .select(emp -> emp.getName());

依赖

复制代码
<dependency>
  <groupId>org.apache.calcite</groupId>
  <artifactId>calcite-linq4j</artifactId>
  <version>1.36.0</version>
</dependency>

Linq4j核心类与接口

  • Linq4j:org.apache.calcite.linq4j.Linq4j,一个实用工具类,可将 java.util.Collection、java.lang.Iterable、java.util.List等集合对象转换为 org.apache.calcite.linq4j.Enumerable
  • Enumerable:接口的职责是定义了对集合进行查询和操作的方法,包括筛选、映射、分组等功能。接口继承了下列三个接口,支持集合的迭代、投影、过滤等操作
    • RawEnumerable (org.apache.calcite.linq4j):返回org.apache.calcite.linq4j.Enumerator,可对Enumerator实现进行迭代
    • Iterable (java.lang):返回java.lang.Iterable,可对Iterable的实现迭代
    • ExtendedEnumerable (org.apache.calcite.linq4j):定义了在集合对象上的操作 例如 select 投影、where 过滤、groupBy 分组 、hashJoin 连接
      因此通过Linq4j转换方法将输入集合转换为Enumerable,这样就可在原始数据上进行操作。

使用案例

使用过滤、投影、分组

  • 投影没有进行映射变换,按原值输出
  • 过滤筛选出大于3的数
  • 最后进行分组,分组后返回的是一个 Grouping 对象,使用sum函数对分组求和,最终输出求和后的结果
    整个操作使用分组后返回的是Grouping对象,因此后续操作基于此对象进行
java 复制代码
        List<Integer> idList = Lists.newArrayList(1,2,3,4,5,6);
        Enumerable<Integer> itEnumerable = Linq4j.asEnumerable(idList);

        Enumerable<Grouping<Boolean, Integer>> result =
        itEnumerable
            .select((a) -> a)
            .where((a) -> a > 3)
            .groupBy(a -> a%2 == 0);

        for (Grouping<Boolean, Integer> item: result) {

            int sum = item.sum(new IntegerFunction1<Integer>() {
                @Override
                public int apply(Integer v0) {
                    return v0;
                }
            });
            System.out.println(item.getKey() + " : " + sum);
        }

通过一个案例,可类推其它方法的使用。

Linq4j在Calcite中的应用

在使用Calcite实现适配多来源数据查询时,需要实现自定义的table,通常需要借助Linq4j提供的方法将集合转换为Enumerable实例,转换过程中依赖asEnumerable方法创建Enumerable实例实例,接着通过select进行对象类型转换。

java 复制代码
public class TableForList extends AbstractTable implements ScannableTable{

    private PersonList personList;

    public TableForList(PersonList personList) {
        this.personList = personList;
    }

    @Override
    public Enumerable<Object[]> scan(DataContext root) {
        return Linq4j.asEnumerable(personList.getPersonList())
            .select(emp -> new Object[]{emp.getId(), emp.getName(), emp.getAge()});
    }
相关推荐
m4Rk_5 分钟前
【论文阅读】Agent 记忆机制(52):Cognitive Scaffold——面向 DeepResearch Agent 的结晶化记忆框架
论文阅读·人工智能·学习·开源·github
薛定e的猫咪11 分钟前
【源码解读版】ContraBAR:用 CPC 对比学习替代变分推断做贝叶斯元 RL
人工智能·深度学习·学习·算法·机器学习
RisunJan16 分钟前
鸿蒙(HarmonyOS NEXT)开发小白入门学习计划表
学习·华为·harmonyos
蒸蒸yyyyzwd32 分钟前
cpp选手备战秋招学习笔记day17
笔记·学习
陈天伟教授1 小时前
【30天学会机械制图 第15 天】项目四 学会看零件图 任务1 学习零件的基本表达方法 (1)
学习·工程制图·机械制图
小张帅三代1 小时前
yolo基础学习笔记
笔记·学习·yolo
zttbee1 小时前
vue学习(白话功能版)
前端·vue.js·学习·前端框架
ouynagda2 小时前
Linux 进程与线程学习笔记
linux·笔记·学习
手握风云-3 小时前
一条消息的旅程:RabbitMQ 学习与实践(四)
学习