IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> antlr4小试牛刀-sql转换成es dsl -> 正文阅读

[大数据]antlr4小试牛刀-sql转换成es dsl

背景

开发es查询程序,每次都要进行编码,大部分代码都是重复代码,实际上最后生成的就是json,简单🤔下,有没有开发人员都会的一种表达语言,将表达语言转换成json,

很明显sql可以,开发人员都会,然后生成项目时,只需用sql来描述,你想要的查询,然后把日期等参数在json中完成替换即可,即可生成查询结果。

es json 如下

{
    "query":{
        "term":{
            "city":{
                "value":"chengdou",
                "boost":1
            }
        }
    },
    "_source":{
        "includes":[
            "name"
        ],
        "excludes":[

        ]
    }
}

antlr4

ANTLR 能够根据用户定义的语法文件自动生成词法分析器和语法分析器,并将输入文本处理为语法分析树。ANTLR 自动生成的编译器高效,能够将开发者从繁杂的编译理论中解放出来,集中精力处理自己的业务逻辑。

ANTRL 4 引入的自动语法分析树创建与遍历机制,极大地提高了语言识别程序的开发效率。我们广为熟知的大数据计算框架的 SQL 解析就是基于 ANTLR,比如 Hive(ANTLR 3)、Spark 2.x(ANTLR 4)、presto(ANTLR 4)等。

定义语法文件

grammar Es;      // 定义一个名为ES的语法,名字与文件名一致



//语法结构
sql: selectoperation;  //定义sql是一个查询操作
selectoperation:
  'select'  field 'from' table where ?  ;   //定义查询语句
field:    ANYTHING                     # ANYTHING  //子规则 *
        |  ID                          # id   //子规则 匹配字母
    ;

table:ID;
where: 'where'  expression ;
expression:  ID '=' ID ;


//词法结构
ID  :   [a-zA-Z]+ ;      // 匹配字母
ANYTHING :   '*' ; // 查询 任务字符

查看生成的语法树

测试SQL
select name from a where city='chengdou'

image.png

生成代码

idea中可以用插件来生成, 只需定义好语法文件即可

image.png

最后生成的结构如下

image.png

测试

// Generated from ANTLR 4.9.2
package com.example.spring.estest;

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import java.util.Arrays;
import java.util.List;

/**
 * This class provides an empty implementation of {@link EsVisitor},
 * which can be extended to create a visitor which only needs to handle a subset
 * of the available methods.
 *
 * @param <T> The return type of the visit operation. Use {@link Void} for
 *            operations with no return type.
 */
public class EsBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements EsVisitor<T> {
    /**
     * {@inheritDoc}
     *
     * <p>The default implementation returns the result of calling
     * {@link #visitChildren} on {@code ctx}.</p>
     */
    @Override
    public T visitSql(EsParser.SqlContext ctx) {
        return visitChildren(ctx);
    }

    /**
     * {@inheritDoc}
     *
     * <p>The default implementation returns the result of calling
     * {@link #visitChildren} on {@code ctx}.</p>
     */
    @Override
    public T visitSelectoperation(EsParser.SelectoperationContext ctx) {
        return visitChildren(ctx);
    }

    /**
     * {@inheritDoc}
     *
     * <p>The default implementation returns the result of calling
     * {@link #visitChildren} on {@code ctx}.</p>
     */
    @Override
    public T visitANYTHING(EsParser.ANYTHINGContext ctx) {
        return visitChildren(ctx);
    }

    /**
     * {@inheritDoc}
     *
     * <p>The default implementation returns the result of calling
     * {@link #visitChildren} on {@code ctx}.</p>
     */
    @Override
    public T visitId(EsParser.IdContext ctx) {
        return visitChildren(ctx);
    }

    /**
     * {@inheritDoc}
     *
     * <p>The default implementation returns the result of calling
     * {@link #visitChildren} on {@code ctx}.</p>
     */
    @Override
    public T visitTable(EsParser.TableContext ctx) {
        return visitChildren(ctx);
    }

    /**
     * {@inheritDoc}
     *
     * <p>The default implementation returns the result of calling
     * {@link #visitChildren} on {@code ctx}.</p>
     */
    @Override
    public T visitWhere(EsParser.WhereContext ctx) {
        return visitChildren(ctx);
    }

    /**
     * {@inheritDoc}
     *
     * <p>The default implementation returns the result of calling
     * {@link #visitChildren} on {@code ctx}.</p>
     */
    @Override
    public T visitExpression(EsParser.ExpressionContext ctx) {
        return visitChildren(ctx);
    }

    public static void main(String[] args) {

        // 对每一个输入的字符串,构造一个 ANTLRStringStream 流 in
        ANTLRInputStream input = new ANTLRInputStream("select name from a where city='chengdou'");
        // 用 in 构造词法分析器 lexer,词法分析的作用是将字符聚集成单词或者符号
        EsLexer lexer = new EsLexer(input);
        // 用词法分析器 lexer 构造一个记号流 tokens
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        // 再使用 tokens 构造语法分析器 parser,至此已经完成词法分析和语法分析的准备工作
        EsParser parser = new EsParser(tokens);
        EsParser.SqlContext sql = parser.sql();

      //找到查询子规则
        EsParser.SelectoperationContext selectOperation = sql.selectoperation();


      //找到查询列
        String[] queryField = (String[]) Arrays.asList(selectOperation.field().getText()).toArray();


      //查看where 表达式
        List<TerminalNode> id = selectOperation.where().expression().ID();

      //查看where 表达式里的内容
        System.out.println(id.get(0).getText());
        System.out.println(id.get(1).getText());


      //生成es的查询语句
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.fetchSource(queryField, new String[0]);
      TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(id.get(0).getText(), id.get(1).getText());
      searchSourceBuilder.query(termQueryBuilder);
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.source(searchSourceBuilder);
      System.out.println(searchRequest.source());

    }
}

结果

{
    "query":{
        "term":{
            "city":{
                "value":"chengdou",
                "boost":1
            }
        }
    },
    "_source":{
        "includes":[
            "name"
        ],
        "excludes":[

        ]
    }
}
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-03-11 22:17:06  更:2022-03-11 22:20:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:51:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码