我刚打酱油去了,不好意思

新人求助,关于es模糊匹配,是否能将文档中的字段值作为关键字去匹配输入的值

回复

es_wei 发起了问题 • 3 人关注 • 0 个回复 • 1595 次浏览 • 2020-05-05 10:40 • 来自相关话题

如何统计索引在某时间范围内新增文档的总存储大小?

回复

ahJames 发起了问题 • 1 人关注 • 0 个回复 • 1100 次浏览 • 2020-05-03 20:55 • 来自相关话题

java查询到es的数据,怎么获取结果的内置字段

God_lockin 回复了问题 • 2 人关注 • 1 个回复 • 2410 次浏览 • 2020-05-03 18:08 • 来自相关话题

新建索引出现重复字段类型不同报错。。求助!!

God_lockin 回复了问题 • 2 人关注 • 2 个回复 • 2602 次浏览 • 2020-05-03 18:06 • 来自相关话题

聚合某个字段,后获取其发帖天数最多的前两个

laoyang360 回复了问题 • 2 人关注 • 1 个回复 • 2429 次浏览 • 2020-05-02 22:51 • 来自相关话题

搜索带 文字和pinyin的内容 文字不匹配但是拼音想同不希望展示如何处理

DRose 回复了问题 • 2 人关注 • 2 个回复 • 1320 次浏览 • 2020-04-30 17:53 • 来自相关话题

中文拼音自定义混合搜索的问题

回复了问题 • 2 人关注 • 1 个回复 • 1679 次浏览 • 2020-04-30 14:34 • 来自相关话题

javaapi根据内置字段查询

liuxing6 回复了问题 • 2 人关注 • 3 个回复 • 1279 次浏览 • 2020-04-30 11:46 • 来自相关话题

elasticsearch使用simple_query_string 如何设置完全匹配?

回复了问题 • 2 人关注 • 1 个回复 • 2616 次浏览 • 2020-04-30 10:00 • 来自相关话题

elasticsearch快照创建后,增量快照是要手动执行,还是自动执行的?

回复

65725738 发起了问题 • 1 人关注 • 0 个回复 • 1305 次浏览 • 2020-04-29 10:57 • 来自相关话题

类比mysql查询,适合新手学习Elasticsearch的DSL查询语句

发表了文章 • 0 个评论 • 7120 次浏览 • 2020-04-29 10:44 • 来自相关话题

Mysql查询与Elasticsearch的DSL查询语句对照


作者:

小森同学,互联网公司搜索开发工程师。

前言


作为新入门的后端开发人员,一般对Mysql,SqlServer这类的关系型数据库或多或少都有了解。当入门Elasticsearch时,发现其DSL语句与关系型数据库的查询完全不一样,不再是那熟悉的语法,顿感门槛有点高。为了方便熟悉关系型数据库查询的同学,更加容易,快捷的理解并掌握DSL基础语法,本文将进行Mysql与DSL语句进行类比。

一、Mysql数据库与Elasticsearch的类比


| 关系型数据库(比如Mysql) | 非关系型数据库(Elasticsearch) |
| ------------------------- | ------------------------------- |
| 数据库 Database | 索引 Index |
| 表 Table | 类型 Type |
| 数据行 Row | 文档 Document |
| 数据列 Column | 字段 Field |
| 约束 Schema | 映射 Mapping |

二、Mysql查询语句与DSL查询类比


Mysql查询语句与Elasticsearch的DSL查询类比,主要通过mysql库中的search_lexicon表和es中的search_lexicon_v1索引进行比较。

2.1 search_lexicon 表结构


sql<br /> CREATE TABLE `search_lexicon` (<br /> `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',<br /> `keyword` varchar(50) NOT NULL DEFAULT '' COMMENT '关键词',<br /> `keyword_crc32` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '关键词校验',<br /> `search_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '类型',<br /> `consumer_id` varchar(50) NOT NULL DEFAULT '' COMMENT '消费者ID',<br /> `num` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '文档数',<br /> `views` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '搜索次数',<br /> `state` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态 0 关闭 1 开启',<br /> `is_del` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否删除 0 正常 1 删除',<br /> `createtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '数据创建时间',<br /> `updatetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '数据最后更新时间',<br /> PRIMARY KEY (`id`),<br /> KEY `idx_search_lexicon_views` (`views`),<br /> KEY `idx_search_lexicon_updatetime` (`updatetime`) USING BTREE,<br /> KEY `idx_search_lexicon_keyword_type` (`keyword_crc32`)<br /> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='搜索词库';<br />

2.2 search_lexicon_v1 索引结构


json<br /> {<br /> "search_lexicon_v1" : {<br /> "mappings" : {<br /> "_doc" : {<br /> "properties" : {<br /> "@timestamp" : {<br /> "type" : "date"<br /> },<br /> "@version" : {<br /> "type" : "long"<br /> },<br /> "consumer_id" : {<br /> "type" : "keyword"<br /> },<br /> "createtime" : {<br /> "type" : "date",<br /> "format" : "yyyy-MM-dd HH:mm:ss||strict_date_optional_time||epoch_millis"<br /> },<br /> "id" : {<br /> "type" : "integer"<br /> },<br /> "is_del" : {<br /> "type" : "integer"<br /> },<br /> "keyword" : {<br /> "type" : "text",<br /> "fields" : {<br /> "standard" : {<br /> "type" : "text",<br /> "analyzer" : "by_standard_no_synonym"<br /> }<br /> },<br /> "analyzer" : "by_max_word_pinyin_no_synonym"<br /> },<br /> "num" : {<br /> "type" : "long"<br /> },<br /> "search_type" : {<br /> "type" : "integer"<br /> },<br /> "state" : {<br /> "type" : "integer"<br /> },<br /> "updatetime" : {<br /> "type" : "date",<br /> "format" : "yyyy-MM-dd HH:mm:ss||strict_date_optional_time||epoch_millis"<br /> },<br /> "views" : {<br /> "type" : "long"<br /> }<br /> }<br /> }<br /> }<br /> }<br /> }<br />

2.3 查询语句对照


注意:dsl查询,每次默认展示10(size默认为10)条

以下的查询条件,是为了写查询而构造的,无任何实质性的意义,仅供mysql查询与dsl查询对比用

布尔查询支持的子查询类型共有四种,分别是:must,should,must_not和filter:

| 查询字句 | 说明 | 类型 |
| -------- | ------------------------------------------------------------ | ---- |
| must | 文档必须符合must中所有的条件,会影响相关性得分 | 数组 |
| should | 文档应该匹配should子句查询的一个或多个 | 数组 |
| must_not | 文档必须不符合must_not 中的所有条件 | 数组 |
| filter | 过滤器,文档必须匹配该过滤条件,跟must子句的唯一区别是,filter不影响查询的score ,会缓存 | 字典 |

A、查询所有数据

mysql


sql<br /> SELECT * FROM search_lexicon<br />

dsl

shell<br /> GET search_lexicon/_search<br /> {<br /> <br /> }<br /> 或<br /> GET search_lexicon/_search<br /> {<br /> "query": {<br /> "match_all": {}<br /> }<br /> }<br />



B、 查询一个条件且条件只有一个值(consumer_id=demo)的数据

mysql

sql<br /> SELECT * FROM search_lexicon WHERE consumer_id='demo'<br />

dsl

shell<br /> GET search_lexicon/_search<br /> {<br /> "query": {<br /> "bool": {<br /> "filter": {<br /> "term": {<br /> "consumer_id": "demo"<br /> }<br /> }<br /> }<br /> }<br /> }<br /> 或<br /> GET search_lexicon/_search<br /> {<br /> "query": {<br /> "bool": {<br /> "filter": [<br /> {<br /> "term": {<br /> "consumer_id": "demo"<br /> }<br /> }<br /> ]<br /> }<br /> }<br /> }<br /> <br /> 两者的区别在于前一个filter是一个对象,filter中只能放一个条件,后者filter是一个数组,里面可以放多个对象(多个查询条件),后续都将按照第二种方式查询<br />



C、 查询一个条件且条件有多个值(consumer_id的值为demo,demo2)的数据

mysql

sql<br /> SELECT * FROM search_lexicon WHERE consumer_id in('demo','demo2')<br />

dsl

shell<br /> GET search_lexicon/_search<br /> {<br /> "query": {<br /> "bool": {<br /> "filter": [<br /> {<br /> "terms": {<br /> "consumer_id": [<br /> "demo",<br /> "demo2"<br /> ]<br /> }<br /> }<br /> ]<br /> }<br /> }<br /> }<br />



D、 查询consumer_id=demo 且 state=1的数据

mysql

sql<br /> SELECT * FROM search_lexicon WHERE consumer_id ='demo' and state=1<br />

dsl

shell<br /> GET search_lexicon/_search<br /> {<br /> "query": {<br /> "bool": {<br /> "filter": [<br /> {<br /> "term": {<br /> "consumer_id": "demo"<br /> }<br /> },<br /> {<br /> "term": {<br /> "state": 1<br /> }<br /> }<br /> ]<br /> }<br /> }<br /> }<br />

E、 查询consumer_id=demo , state=1 且 is_del<>1的数据

mysql

sql<br /> SELECT * FROM search_lexicon WHERE consumer_id ='demo' and state=1 and is_del <>1<br />

dsl

shell<br /> GET search_lexicon/_search<br /> {<br /> "query": {<br /> "bool": {<br /> "filter": [<br /> {<br /> "term": {<br /> "consumer_id": "demo"<br /> }<br /> },<br /> {<br /> "term": {<br /> "state": 1<br /> }<br /> }<br /> ],<br /> "must_not": [<br /> {<br /> "term": {<br /> "is_del": {<br /> "value": 1<br /> }<br /> }<br /> }<br /> ]<br /> }<br /> }<br /> }<br />

F、查询Sconsumer_id ='demo' or (state=1 and is_del =0)的数据

mysql

sql<br /> SELECT * FROM search_lexicon WHERE consumer_id ='demo' or (state=1 and is_del =0)<br />

dsl

shell<br /> GET search_lexicon/_search<br /> {<br /> "query": {<br /> "bool": {<br /> "should": [<br /> {<br /> "term": {<br /> "consumer_id": {<br /> "value": "demo"<br /> }<br /> }<br /> },<br /> {<br /> "bool": {<br /> "filter": [<br /> {<br /> "term": {<br /> "state": 1<br /> }<br /> },<br /> {<br /> "term": {<br /> "is_del": 0<br /> }<br /> }<br /> ]<br /> }<br /> }<br /> ]<br /> }<br /> }<br /> }<br />



G、在F的基础上,查询指定字段

mysql

sql<br /> SELECT id,keyword,consumer_id,num,views,state,is_del FROM search_lexicon WHERE consumer_id ='demo' or (state=1 and is_del =0)<br />

dsl

shell<br /> GET search_lexicon/_search<br /> {<br /> "query": {<br /> "bool": {<br /> "should": [<br /> {<br /> "term": {<br /> "consumer_id": {<br /> "value": "demo"<br /> }<br /> }<br /> },<br /> {<br /> "bool": {<br /> "filter": [<br /> {<br /> "term": {<br /> "state": 1<br /> }<br /> },<br /> {<br /> "term": {<br /> "is_del": 0<br /> }<br /> }<br /> ]<br /> }<br /> }<br /> ]<br /> }<br /> },<br /> "_source": {<br /> "includes": [<br /> "id",<br /> "keyword",<br /> "num",<br /> "is_del",<br /> "state",<br /> "consumer_id",<br /> "views"<br /> ]<br /> }<br /> }<br />



H、在G的基础上,增加排序

mysql

sql<br /> SELECT id,keyword,consumer_id,num,views,state,is_del FROM search_lexicon WHERE consumer_id ='demo' or (state=1 and is_del =0) ORDER BY state DESC,id DESC<br />

dsl

shell<br /> GET search_lexicon/_search<br /> {<br /> "query": {<br /> "bool": {<br /> "should": [<br /> {<br /> "term": {<br /> "consumer_id": {<br /> "value": "demo"<br /> }<br /> }<br /> },<br /> {<br /> "bool": {<br /> "filter": [<br /> {<br /> "term": {<br /> "state": 1<br /> }<br /> },<br /> {<br /> "term": {<br /> "is_del": 0<br /> }<br /> }<br /> ]<br /> }<br /> }<br /> ]<br /> }<br /> },<br /> "_source": {<br /> "includes": [<br /> "id",<br /> "keyword",<br /> "num",<br /> "is_del",<br /> "state",<br /> "consumer_id",<br /> "views"<br /> ]<br /> },<br /> "sort": [<br /> {<br /> "state": {<br /> "order": "desc"<br /> }<br /> },<br /> {<br /> "id": {<br /> "order": "desc"<br /> }<br /> }<br /> ]<br /> }<br />



I、在H的基础上,添加分页

mysql

sql<br /> SELECT id,keyword,consumer_id,num,views,state,is_del FROM search_lexicon WHERE consumer_id ='demo' or (state=1 and is_del =0) ORDER BY state DESC,id DESC LIMIT 0,20<br />

dsl

```shell
GET search_lexicon/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"consumer_id": {
"value": "demo"
}
}
},
{
"bool": {
"filter": [
{
"term": {
"state": 1
}
},
{
"term": {
"is_del": 0
}
}
]
}
}
]
}
},
"_source": {
"includes": [
"id",
"keyword",
"num",
"is_del",
"state",
"consumer_id",
"views"
]
},
"sort": [
{
"state": {
"order": "desc"
}
},
{
"id": {
"order": "desc"
}
}
],
"from": 0,
"size": 20
}

from 是一个偏移量,size为每页显示条数

<br /> <br /> <br /> <br /> **J、去重查询**<br /> <br /> mysql<br /> <br /> sql
SELECT DISTINCT state FROM search_lexicon WHERE consumer_id = 'demo'
<br /> <br /> dsl<br /> <br /> shell

通过折叠去重查询

GET search_lexicon/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"consumer_id": {
"value": "demo"
}
}
}
]
}
},
"collapse": {
"field": "state"
}
}
<br /> <br /> <br /> <br /> **K、分组查询**<br /> <br /> mysql<br /> <br /> sql
SELECT FROM search_lexicon WHERE consumer_id = 'demo' GROUP BY state
<br /> <br /> dsl<br /> <br /> shell
GET search_lexicon/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"consumer_id": {
"value": "demo"
}
}
}
]
}
},
"size": 0,
"aggs": {
"aaa": {
"terms": {
"field": "state",
"size": 10
}
}
}
}

<br /> <br /> **L、模糊匹配**<br /> <br /> mysql<br /> <br /> sql
SELECT
FROM search_lexicon WHERE consumer_id="demo" and keyword LIKE '%渴望%'
<br /> <br /> dsl<br /> <br /> shell
GET search_lexicon/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"consumer_id": {
"value": "demo"
}
}
}
],
"must": [
{
"match": {
"keyword": "渴望"
}
}
]
}
}
}
```

三、总结

Mysql查询与DSL查询对照,用心体会二者之间,上下文之间,各查询条件的差异与相似,快速掌握DSL的语法结构,You can do it!



声明:

本文版权归作者所有,未经许可不得擅自转载或引用。
原文地址:https://elasticsearch.cn/article/13760

如何自動更改keyvalue 在elasticsearch 裡

回复

zerolim820 发起了问题 • 1 人关注 • 0 个回复 • 1766 次浏览 • 2020-04-29 10:43 • 来自相关话题

ES异常退出,有没有好的排查思路呢?

locatelli 回复了问题 • 2 人关注 • 1 个回复 • 1967 次浏览 • 2020-04-29 06:14 • 来自相关话题

ElasticSearch布尔查询超限

hyzz 回复了问题 • 2 人关注 • 2 个回复 • 1651 次浏览 • 2020-04-28 15:51 • 来自相关话题

es7.6.2源码编译打包,如何打某个plugin

回复

superzheng 发起了问题 • 1 人关注 • 0 个回复 • 2322 次浏览 • 2020-04-28 14:52 • 来自相关话题