Sql与OpenSearch查询语法的对比

OpenSearch的主战场虽然在“搜索”上,但是对大部分的Sql用法也是有很好的支持的,虽然语法可能不尽相同,但是实现的效果大致一样,因此,下文将一一介绍Sql主流的功能,在OpenSearch里是如何实现的。

常见用法对比

大部分的开发者应该对SQL是再熟悉不过了,因此这里反客为主,咱们以SQL执行逻辑的顺序去介绍OpenSearch是如何实现如下的操作单元的,如下是SQL的执行逻辑:

(1)FROM(2)ON(3)JOIN(4)WHERE(5)GROUP BY(6)WITH {CUBE | ROLLUP}(7)HAVING(8)SELECT(9)DISTINCT  (10)ORDER BY(11)LIMIT 。

1.FROM:

    • SQL:from后面一般接的是表名,也可以接一个数据集(一个能查询部分数据的SQL,这里不考虑嵌套这种复杂结构)。

    • OpenSearch:是以应用为表单位,一个应用对应一种业务逻辑,因此在搜索的时候无需指定表名,只需要在SDK(以Java SDK的搜索 Demo为例)中指定对应的(host、appname、accessKey、secret)即可。

2.ON和JOIN:

    • SQL:一般在多表join的场景中join用于连接两表或者两个数据集,而on是对表与表之前join关系的限制,通俗点说就是这两个表在满足何种条件的时候才可join。

    • OpenSearch:join逻辑是在创建应用时,定义应用结构的时候配置的,之后,数据进入OpenSearch就会被join成一个大宽表,具体的实现逻辑可以OpenSearch同步数据原理进行查看,on一般可在配置数据源的时候,对每张表进行限制(过滤掉不满足条件的记录)。

3.WHERE:

    • SQL:类似于过滤,保留符合条件的数据。

    • OpenSearch:两种子句可以实现过滤(queryfilter),二者的区别则query是倒排索引,查询效率高,但功能没有filter灵活,无法实现带表达式的计算逻辑,而filter是正排索引,查询效率要低于query,但支持表达式和函数的计算逻辑,功能更丰富。

4.GROUP BY :

    • SQL:group by在SQL中的用法相当多,而且比较复杂,这里简单的概括为分组统计(常规的统计有count、sum、max、min、avg等)。

    • OpenSearch:可以使用aggregate子句实现group by的功能。

5.WITH 和 HAVING的功能OpenSearch 现阶段暂时无法支持,需要用户在返回的结果中自行实现

6.SELECT:

    • SQL:用于限定返回的数据中,每条记录返回哪些字段

    • OpenSearch:可以通过界面和参数两种方法配置,分别是默认展示字段fetch_fields

7.DISTINCT :

    • SQL:根据某个字段值对比,删除重复的记录。

    • OpenSearch:同样通过distinct子句实现该功能,并且在功能上比SQL的distinct更为丰富,不仅可以去重,还可以打散,有点像分组topN的概念。

8.ORDER BY:

    • SQL:用于根据某个字段,或者某个表达式的结果进行排序(正序/倒序)

    • OpenSearch:可以通过sort子句时实现,当然OpenSearch的排序,不仅仅是根据某个字段排序,还可以通过文档得分进行排序,还可以根据算法模型,对文档进行干预,再结合文档分和字段内容,跟文档进行综合排序,排序的方式很多具体可以参考排序表达式

9.LIMIT :

    • SQL:limit用于翻页,有两个参数,start,hit,分别表示从第几条开始,返回几条。

    • OpenSearch:可以通过config子句,设置start,hit值,实现翻页的效果。

其他实用用法对比

1.LIKE和 NOT LIKE:

    • SQL:用于模糊匹配,如:like '%北京%',检索字段内容中包含‘北京’的记录

    • OpenSearch:query子句用于召回的逻辑,是对字段内容进行分词,将分词后的item匹配上的记录进行返回,加上OpenSearch提供了丰富并且强大的分析器,可以完美替代,并弥补SQL中like效率低的问题;not like 也可以通过query子句中ANDNOT的用法进行代替。

2.IN:

    • SQL:IN 操作符允许在 WHERE 子句中规定多个值,如:WHERE column_name IN ( value1 value2 ,...);

    • OpenSearch:可以在filter里配置in/not实现。