Elasticsearch7.X的SQL access实现

前言

elasticsearch7.X出来也有一段时间了,正好这次让我给项目中的elasticsearch升级版本,就去了解了一下我需要升级的这块东西。

安装

docker pull elasticsearch:7.7.0
docker run --name elasticsearch -d -e ES_JAVA_OPTS="-Xms512m -Xmx512m" -e "discovery.type=single-node" -p 9200:9200 -p 9300:9300 elasticsearch:7.7.0
看到这个就说明装好了

image.png

可以参考docker部署运行ES

SQL access

sql rest api

这次升级也主要是升级这里,系统之前支持通过sql查询elasticsearch,之前系统使用的是elasticsearch_sql来把用户输入的sql转换为elasticsearch的query dsl语句去查询。
可以先去看看官方文档
我们在新版本中弃用es-sql的包,直接使用新版本的sql rest aqi。在项目中引入es的包,通过它给的api去调用es的接口就行了。直接上代码测试
先在es中添加测试数据,可以用postman调用es的rest接口
http://127.0.0.1:9200/_index/_type/_id,如果id存在则是更新

image.png

测试数据

测试

在代码里我通过restTemplate去请求,来试试简单的查询吧

        String elasticsearchAddress = "http://172.19.5.57:9200/_sql?format=json";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("query","select name,age from jianshu group by name,age ");
        JSONObject  results = restTemplate.postForObject(elasticsearchAddress,jsonObject,JSONObject.class);
        if (jsonObject.get("cursor") == null){
            JSONArray columns = results.getJSONArray("columns");
            List<Column> columnList = JSONArray.parseArray(columns.toJSONString(),Column.class);
            JSONArray values = results.getJSONArray("rows");
            System.out.println("results:" + results);
            List<JSONObject> res = JSONArray.parseArray(JSONObject.toJSONString(values),JSONArray.class).stream()
                    .map(p -> {
                        JSONObject user = new JSONObject();
                        for (int i = 0; i< columnList.size(); i++){
                            user.fluentPut(columnList.get(i).getName(),p.get(i));
                        }
                        return user;
                    }).collect(Collectors.toList());
            System.out.println("res:" + res);
        } else {
            System.out.println(results);
        }
//打印结果
results:{"cursor":"k8OvAwFaAWMBB2ppYW5zaHWYAQEBCWNvbXBvc2l0ZQdncm91cGJ5AAD/AgAHY2ZjYTZmYQEMbmFtZS5rZXl3b3JkAAABAAAACDFhMmY5MTA2AQthZ2Uua2V5d29yZAAAAQAA6AcBCgIHY2ZjYTZmYQAC566A5LmmCDFhMmY5MTA2AAIxMAACAQAAAAABAP////8PAAAAAAAAAAAAAAAAAVoDAAICAAAAAAAA/////w8CAWsHY2ZjYTZmYQAAAWsIMWEyZjkxMDYAAAEDAA==","columns":[{"name":"name","type":"text"},{"name":"age","type":"text"}],"rows":[["简书","10"]]}
res:[{"name":"简书","age":"10"}]
@Data
public class Column {

    private String name;

    private String type;
}

从返回结果来看,由于es节约性能。是把行列分开返回的(从官方文档也可以看出来)。所以我们拿到结果后转成我们常见的key,value的形式。

一个小插曲

在正式环境上我处理列数据时

List<String> columnList = JSONObject.parseArray(results.getString("columns"))
                .stream()
                .map(p -> ((JSONObject) p).getString("name"))
                .collect(Collectors.toList());

得到的结果是正确的


image.png

但是我在测试代码上那样获取列数据时是这样的,返回来的结果都是一样的,可能是我哪个包的版本不一致。后面再检查下。


image.png

cursor

从结果看还有另外一个返回值cusor,从官网文档上看到用于大数据的查询(也就是分页),在我们使用分页时可以添加参数 jsonObject.put("fetch_size",5);
特别注意:在分页后,想要查询后面数据时,请求时参数只能有cursor这一个。并且返回来的数据不再有列数据,所以我们在正式使用时需要在分页查询第一次后把列数据保存下来。
如下面官网例子所示

image.png

SQL JDBC

最开始我就走偏了,用了这个,结果发现需要es的白金版会员才能使用,所以感觉没啥用,毕竟要花钱。简单实现了一下。

实现

使用jdbc需要先引入x-pack包

<dependency>
  <groupId>org.elasticsearch.plugin</groupId>
  <artifactId>x-pack-sql-jdbc</artifactId>
  <version>7.13.0</version>
</dependency>

然后就是关于es操作的service以及对应serviceImpl了,主要就是去实现ElasticsearchRepository以及父类的方法。

public interface UserService {

    public void saveUser(User user);

    public User findUser(Long id);
}

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserRepository userRepository;

    @Override
    public void saveUser(User user) {
        userRepository.save(user);
    }

    @Override
    public User findUser(Long id) {
        return userRepository.findById(id).get();
    }
}
public interface UserRepository extends ElasticsearchRepository<User, Long> {
}
@Data
@Accessors(chain = true)
@Document(indexName = "jianshu", type = "author")
public class User implements Serializable {

    @Id
    private Long id;

    private String name;

    private String age;
}

实现类写好后,咱们就可以简单测试一下

@Test
    public void save() {
        userService.saveUser(new User()
                .setName("简书jdbc").setAge("11"));
    }
image.png
 @Test
    public void findById() {
        User byId = userService.findUser(1L);
        System.out.println(byId);
    }
image.png

这其中也是踩了一些坑的,不过具体久了忘记了.....欢迎留言讨论

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354