Elasticsearch SQL插件调研与问题整理

        在最新的es8.11版本中,开始有了es|ql语言。非常接近sql,但是还是不太一样。而在之前的版本中,sql能力很弱,并且属于白金版本的内容。也就是说需要氪金才能体验,才能使用。

        我是es研发工程师。负责公司内部的es集群的日常维护(万亿级规模),升级改造与优化。最近在做一件事情,需要能够降低es的学习使用成本,给公司更多的人带来方便,即使不懂es也能用起来。所以需要一个好用的API,不再去写es的哪些语法。

        本来考虑使用query_string语法来支持。业务人员来自己自由组装逻辑表达式即可。但是给大家体验后,普遍觉得比较麻烦,比较难。

        想一下,既然难,那什么才是容易的呢。对于开发人员来说,应该sql能力是必备的能力,属于基本不用再学的东西。于是就调研了es里边能用的sql插件。

        通过大量调研,普遍的方案,都是open Distro,但是版本停留在了7.10版本。另外一个插件,nlpChina,已经更新到了8.10版本,更新非常及时。于是就选用它。但是我发现插件普遍存在性能问题。主要是sql的原语和es的原语对照不齐。且插件为了普遍性,损失了很大的性能。通过这篇文章,就整理出来插件中存在的问题。我会先写sql语句,以及找到其转化后的DSL语句。并指出转换后存在的问题。

ES-sql插件(搜索语法)

参考文档

Basic Queries - Open Distro Documentation

sql插件地址

https://github.com/NLPchina/elasticsearch-sql

语法支持

SELECT [DISTINCT] (* | expression) [[AS] alias] [, ...]

FROM index_name

[WHERE predicates]

[GROUP BY expression [, ...]

 [HAVING predicates]]

[ORDER BY expression [IS [NOT] NULL] [ASC | DESC] [, ...]]

[LIMIT [offset, ] size]

NLPchina/elasticsearch-sql存在的问题

问题汇总

在sql中where后边的逻辑符号测试。存在以下问题。

运算符

描述

是否支持

是否存在问题

=

等于

原语问题

<>

不等于。注释:在 SQL 的一些版本中,该操作符可被写成 !=

原语问题

>

大于

<

小于

>=

大于等于

<=

小于等于

BETWEEN

在某个范围内

LIKE

搜索某种模式

IN

指定针对某个列的多个可能值

原语问题

IS  NULL

为空

IS NOT NULL

不为空

解析语句臃肿

问题1- =语法问题

此问题,存在严重的性能问题。虽然最终的检索结果,可能是一样的。但是底层逻辑执行绕了一大圈。等号被解析成了match_phrase,始终是要分词的,在分词之后,又走的检索逻辑,且要计算距离。严重损耗性能!

select * from product-index where price=2  limit 10

sql2dsl

{
	"from": 0,
	"size": 10,
	"query": {
		"bool": {
			"filter": [{
				"bool": {
					"must": [{
						"match_phrase": {
							"price": {
								"query": 2
							}
						}
					}],
					"boost": 1.0
				}
			}],
			"boost": 1.0
		}
	}
}

解决方式1:需要修改语法,指定为精准匹配

select * from product-index where price=term("10") limit 10

sql2dsl

{
	"from": 0,
	"size": 10,
	"query": {
		"bool": {
			"filter": [{
				"bool": {
					"must": [{
						"term": {
							"price": {
								"value": "10"
							}
						}
					}],
					"boost": 1.0
				}
			}],
			"boost": 1.0
		}
	}
}

解决方式2:TODO 修改插件源码中的解析逻辑。需要考虑等号的逻辑。在sql语句中,等号的原语,应该是精准匹配。

问题2- in 语法问题

此问题和问题1类似,同样存在被解析成match_phrase的问题。同时,更严重的问题是,in原语它解析成了should。这里实际上应该使用terms语法。因为should实际上被用来做加分操作。并不符合sql中in的原语。

select * from product-index where price in(1,2) limit 10

sql2dsl

{
	"from": 0,
	"size": 10,
	"query": {
		"bool": {
			"filter": [{
				"bool": {
					"must": [{
						"bool": {
							"should": [{
								"match_phrase": {
									"price": {
										"query": 1
									}
								}
							}, {
								"match_phrase": {
									"price": {
										"query": 2
									}
								}
							}],
							"boost": 1.0
						}
					}],
					"boost": 1.0
				}
			}],
			"boost": 1.0
		}
	}
}

问题解决方式1:使用以下形式。

select * from product-index where price=terms(1,2) limit 10

问题解决方式2:修改源码逻辑。

问题3- <> 语法问题

此问题和上述问题相似,被解析成为了 match_phrase

select * from product-index where price<>2  limit 10

sql2dsl

{
	"from": 0,
	"size": 10,
	"query": {
		"bool": {
			"filter": [{
				"bool": {
					"must": [{
						"bool": {
							"must_not": [{
								"match_phrase": {
									"price": {
										"query": 2
									}
								}
							}],
							"boost": 1.0
						}
					}],
					"boost": 1.0
				}
			}],
			"boost": 1.0
		}
	}
}

select * from product-index where price<>term(2)  limit 10

问题解决方式:改源码

问题4 IS NOT NULL 语法问题

语句非常臃肿。用了两层must not,来表示must

select * from product-index where price IS NOT NULL  limit 10

sql2dsl

{
	"from": 0,
	"size": 10,
	"query": {
		"bool": {
			"filter": [{
				"bool": {
					"must": [{
						"bool": {
							"must_not": [{
								"bool": {
									"must_not": [{
										"exists": {
											"field": "price",
											"boost": 1.0
										}
									}],
									"boost": 1.0
								}
							}],
							"boost": 1.0
						}
					}],
					"boost": 1.0
				}
			}],
			"boost": 1.0
		}
	}
}

问题5-解析后的条件,都带着 filter

问题:会滥用缓存

{
	"from": 0,
	"size": 10,
	"query": {
		"bool": {
			"filter": [{
				"bool": {
					"must": [{
						"match_phrase": {
							"price": {
								"query": 2
							}
						}
					}],
					"boost": 1.0
				}
			}],
			"boost": 1.0
		}
	}
}

问题解决方法1:考虑在查询的时候,指定不缓存。

问题解决方法2:修改逻辑。

问题6- group by 语法

原语没有问题,解析对应的是es中的 terms桶聚合。shard_size": 5000 设置的过大。

select * from product-index where price=2    GROUP BY  price  limit 10

sql2dsl

{
	"from": 0,
	"size": 0,
	"query": {
		"bool": {
			"filter": [{
				"bool": {
					"must": [{
						"match_phrase": {
							"price": {
								"query": 2
							}
						}
					}],
					"boost": 1.0
				}
			}],
			"boost": 1.0
		}
	},
	"aggregations": {
		"price": {
			"terms": {
				"field": "price",
				"size": 10,
				"shard_size": 5000,
				"min_doc_count": 1,
				"shard_min_doc_count": 0,
				"show_term_doc_count_error": false,
				"order": [{
					"_count": "desc"
				}, {
					"_key": "asc"
				}]
			}
		}
	}
}

问题7 聚合场景下的 order by问题

  1. 这里的order by 既对查询生效了,又对聚合结果生效了。
  2. 聚合结果数无法选择,这里默认只有10条。

select * from product-index where price=2    GROUP BY  price ORDER BY price  asc  limit 0

sql2dsl

{
	"from": 0,
	"size": 0,
	"query": {
		"bool": {
			"filter": [{
				"bool": {
					"must": [{
						"match_phrase": {
							"price": {
								"query": 2
							}
						}
					}],
					"boost": 1.0
				}
			}],
			"boost": 1.0
		}
	},
	"sort": [{
		"price": {
			"order": "asc"
		}
	}],
	"aggregations": {
		"price": {
			"terms": {
				"field": "price",
				"size": 10,
				"shard_size": 5000,
				"min_doc_count": 1,
				"shard_min_doc_count": 0,
				"show_term_doc_count_error": false,
				"order": {
					"_key": "asc"
				}
			}
		}
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/224847.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Netty线程模型

Netty线程模型 Netty中两个线程池, 分别是BossGroup和WorkGroup, 线程模型如下图所示&#xff1a; 模型解释&#xff1a; Netty 抽象出两组线程池BossGroup和WorkerGroup&#xff0c;BossGroup专门负责接收客户端的连接, WorkerGroup专门负责网络的读写BossGroup和WorkerGr…

面试官:说说Loader和Plugin的区别

面试官&#xff1a;说说Loader和Plugin的区别&#xff1f;编写Loader&#xff0c;Plugin的思路&#xff1f; 一、区别 loader 是文件加载器&#xff0c;能够加载资源文件&#xff0c;并对这些文件进行一些处理&#xff0c;诸如编译、压缩等&#xff0c;最终一起打包到指定的文…

【Unity动画】Sprite 2D精灵创建编辑到动画

如何切图&#xff08;sprite editor&#xff09; 有时候一张图可能包含了很多张子图&#xff0c;就需要在Unity 临时处理一下&#xff0c;切开&#xff0c;比如动画序列帧图集 虽然我们可以在PS里面逐个切成一样的尺寸导出多张&#xff0c;再放回Unity&#xff0c;但是不需要这…

docker镜像与容器的基本操作,容器打包以及镜像迁移

docker镜像拉取---docker pull docker pull image_name[:tag] 这是直接拉取官方镜像 image_name: 镜像的名称&#xff0c;例如 ubuntu, nginx, mysql 等。tag: 镜像的标签&#xff0c;表示版本或者特定的标识。如果未指定标签&#xff0c;默认为 latest。 例如&#xff0c;…

Qt之QGraphicsView —— 笔记1.2:将QGraphicsView放置主窗口上,绘制简单图元(附完整源码)

效果 相关类介绍 QGraphicsView类提供了一个小部件,用于显示QGraphicsScene的内容。QGraphicsView在可滚动视口中可视化。QGraphicsView将滚动其视口,以确保该点在视图中居中。 QGraphicsScene类 提供了一个用于管理大量二维图形项的场景。请注意,QGraphicsScene没有自己的视…

【Spring】依赖注入之属性注入详解

前言&#xff1a; 我们在进行web开发时&#xff0c;基本上一个接口对应一个实现类&#xff0c;比如IOrderService接口对应一个OrderServiceImpl实现类&#xff0c;给OrderServiceImpl标注Service注解后&#xff0c;Spring在启动时就会将其注册成bean进行统一管理。在Co…

CleanMyMac最新版本4.14.5有哪些新功能?

CleanMyMac是一款专业的Mac清理工具&#xff0c;只需要一键智能清理&#xff0c;便能让Mac恢复原始的性能&#xff0c;是MAC系统非常好用的工具。CleanMyMac4.14.5自身拥有一个安全数据库&#xff0c;它是一个项目列表&#xff0c;拥有一定的规格&#xff0c;可以确保软件能够正…

销售技巧培训课程内容如何设计才能更好地落地

销售技巧培训课程内容如何设计才能更好地落地 在当今竞争激烈的市场环境中&#xff0c;销售人员的角色和作用越来越重要&#xff0c;是公司业绩来源的核心&#xff0c;也是公司能否在激烈竞争的市场中立于不败之地的关键。 因此&#xff0c;对销售人员进行有效的销售技巧培训&a…

两种伦敦银缺口 如何为我们的交易服务?

我们做伦敦银也会碰到缺口&#xff0c;有的朋友会说伦敦银不是24小时交易的品种吗&#xff1f;怎么有缺口呢&#xff1f;虽说伦敦银是24小时交易的品种&#xff0c;但是在北京时间的凌晨也会停止交易一段时间&#xff0c;这是平台结算时间。在亚盘早段伦敦银重新开盘之后&#…

40 mysql join 的实现

前言 join 是一个我们经常会使用到的一个 用法 我们这里 看一看各个场景下面的 join 的相关处理 测试数据表如下, 两张测试表, tz_test, tz_test03, 表结构 一致 CREATE TABLE tz_test (id int(11) unsigned NOT NULL AUTO_INCREMENT,field1 varchar(128) DEFAULT NULL,fi…

AWS攻略——创建VPC

文章目录 创建一个可以外网访问的VPCCIDR主路由表DestinationTarget 主网络ACL入站规则出站规则 子网创建EC2测试连接创建互联网网关&#xff08;IGW&#xff09;编辑路由表 知识点参考资料 在 《AWS攻略——VPC初识》一文中&#xff0c;我们在AWS默认的VPC下部署了一台可以SS…

Tomcat管理功能使用

前言 Tomcat管理功能用于对Tomcat自身以及部署在Tomcat上的应用进行管理的web应用。在默认情况下是处于禁用状态的。如果需要开启这个功能&#xff0c;需要配置管理用户&#xff0c;即配置tomcat-users.xml文件。 &#xff01;&#xff01;&#xff01;注意&#xff1a;测试功…

Numpy 实现C4.5决策树

C4.5 信息增益比实现决策树 信息增益比 g R ( D , A ) g ( D , A ) H ( D ) g_{R}(D, A)\frac{g(D, A)}{H(D)} gR​(D,A)H(D)g(D,A)​ 其中&#xff0c; g ( D , A ) g(D,A) g(D,A)是信息增益&#xff0c; H ( D ) H(D) H(D)是数据集 D D D的熵 代码实现 import numpy as …

探究Spring Boot 中实现跨域的几种方式

文章目录 前言1. 使用CrossOrigin注解2. 使用WebMvcConfigurer配置3. 使用Filter配置4. 使用全局配置结束语 前言 在现代Web应用中&#xff0c;由于安全性和隐私的考虑&#xff0c;浏览器限制了从一个域向另一个域发起的跨域HTTP请求。解决这个问题的一种常见方式是实现跨域资…

webpack学习-3.管理输出

webpack学习-3.管理输出 1.简单练手2.设置 HtmlWebpackPlugin3.清理 /dist 文件夹4.manifest5.总结 1.简单练手 官网的第一个预先准备&#xff0c;是多入口的。 const path require(path);module.exports {entry: {index: ./src/index.js,print: ./src/print.js,},output: …

基于SSM框架家电商城系统分前后台【项目源码+数据库脚本+报告】

一、项目简介 本项目是一套基于SSM框架家电商城系统&#xff0c;主要针对计算机相关专业的正在做bishe的学生和需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目可以直接作为bishe使用。 项目都经过严格调试&#xff0c;确保可以运行…

Mysql 日期函数大全

一、时间函数 &#xff08;一&#xff09;、获取当前时间 1、NOW() 获取当前日期和时间&#xff0c;在程序一开始执行便拿到时间 返回格式 YYYY-MM-DD hh:mm:ss eg&#xff1a; NOW() 得到 2023-12-03 12:20:02 NOW(),SLEEP(2),NOW() 得到 2023-12-03 12:20:02 | 0 | 2023-…

HeyGen推出Avatar2.0:AI视频翻译工具引领虚拟分身创作新时代

在数字创意领域迈向新的里程碑&#xff0c;HeyGen公司正式推出了Avatar2.0&#xff0c;这是一款令人惊叹的AI视频翻译工具&#xff0c;仅需短短5分钟&#xff0c;用户即可在手机上打造一个逼真的虚拟分身。HeyGen的这一最新创新标志着他们在多模态内容生成领域的持续引领地位&a…

对象数组根据布尔值true和false进行排序——js基础积累

对象数组根据布尔值true和false进行排序——js基础积累 应用场景&#xff1a;效果图如下&#xff1a;根据布尔值进行排序总结&#xff1a;1.true的放前面——算降序排列2.true的放后面——算升序排列 应用场景&#xff1a; 最近在写后台管理系统的时候&#xff0c;遇到一个需求…

MySQL:update set的坑

目录 一、问题描述 二、为何会出现这样的问题&#xff1f; 三、正确的方案 一、问题描述 我在修改mysql数据表时&#xff0c;看到下面的现象。 我表中原始数据如下&#xff1a; 执行了下面的修改&#xff0c;显示执行成功。 update user_function_record_entity set open_…