DSL语言高级查询
DSL由叶子查询子句和复合查询子句两种子句组成
无查询条件:无查询条件是查询所有,默认是查询所有的,或者使用match_all表示所有
GET /es_db/_doc/_search { "query":{ "match_all":{} } }
有查询条件:
叶子条件查询(单字段查询条件) 3.1.1 模糊匹配 模糊匹配主要是针对文本类型的字段,文本类型的字段会对内容进行分词,对查询时,也会对搜索条件进行分词,然后通过倒排索引查找到匹配的数据,模糊匹配主要通过match等参数来实现 match : 通过match关键词模糊匹配条件内容 prefix : 前缀匹配 regexp : 通过正则表达式来匹配数据
match的复杂用法
match条件还支持以下参数:
query : 指定匹配的值
operator : 匹配条件类型
and : 条件分词后都要匹配
or : 条件分词后有一个匹配即可(默认)
minmum_should_match : 指定最小匹配的数量
3.1.2 精确匹配
term : 单个条件相等
terms : 单个字段属于某个值数组内的值
range : 字段属于某个范围内的值
exists : 某个字段的值是否存在
ids : 通过ID批量查询
组合条件查询(多条件查询)
组合条件查询是将叶子条件查询语句进行组合而形成的一个完整的查询条件
bool : 各条件之间有and,or或not的关系
must : 各个条件都必须满足,即各条件是and的关系
should : 各个条件有一个满足即可,即各条件是or的关系
must_not : 不满足所有条件,即各条件是not的关系
filter : 不计算相关度评分,它不计算_score即相关度评分,效率更高
constant_score : 不计算相关度评分
must/filter/shoud/must_not 等的子条件是通过 term/terms/range/ids/exists/match 等叶子条件为参数的
注:以上参数,当只有一个搜索条件时,must等对应的是一个对象,当是多个条件时,对应的是一个数组
连接查询(多文档合并查询)
父子文档查询:parent/child
嵌套文档查询: nested
DSL查询语言中存在两种:查询DSL(query DSL)和过滤DSL(filter DSL):区别
Query方式查询:案例
根据名称精确查询姓名 term, term查询不会对字段进行分词查询,会采用精确匹配
POST /es_db/_doc/_search { "query": { "term": { "name": "admin" } } }
类似:SQL: select * from student where name = ‘admin’
注意: 采用term精确查询, 查询字段映射类型属于为keyword
根据备注信息模糊查询 match, match会根据该字段的分词器,进行分词查询
POST /es_db/_doc/_search { "from": 0, "size": 2, "query": { "match": { "address": "广州" } } } 类似:SQL: select * from user where address like '%广州%' limit 0, 2
多字段模糊匹配查询与精准查询 multi_match
POST /es_db/_doc/_search { "query":{ "multi_match":{ "query":"张三", "fields":["address","name"] } } } 类似:SQL: select * from student where name like '%张三%' or address like '%张三%'
未指定字段条件查询 query_string , 含 AND 与 OR 条件
POST /es_db/_doc/_search { "query":{ "query_string":{ "query":"广州 OR 长沙" } } }
指定字段条件查询 query_string , 含 AND 与 OR 条件
POST /es_db/_doc/_search { "query":{ "query_string":{ "query":"admin OR 长沙", "fields":["name","address"] } } }
范围查询
注:json请求字符串中部分字段的含义 range:范围关键字 gte 大于等于 lte 小于等于 gt 大于 lt 小于 now 当前时间
POST /es_db/_doc/_search { "query" : { "range" : { "age" : { "gte":25, "lte":28 } } } } 类似:SQL: select * from user where age between 25 and 28
分页、输出字段、排序综合查询
POST /es_db/_doc/_search { "query" : { "range" : { "age" : { "gte":25, "lte":28 } } }, "from": 0, "size": 2, "_source": ["name", "age", "book"], "sort": {"age":"desc"} }
Filter过滤器方式查询,它的查询不会计算相关性分值,也不会对结果进行排序, 因此效率会高一点,查询的结果可以被缓存
POST /es_db/_doc/_search { "query" : { "bool" : { "filter" : { "term":{ "age":25 } } } } }
总结:
1. match match:模糊匹配,需要指定字段名,但是输入会进行分词,比如"hello world"会进行拆分为hello和world,然后匹配,如果字段中包含hello或者world,或者都包含的结果都会被查询出来,也就是说match是一个部分匹配的模糊查询。查询条件相对来说比较宽松。 2. term term: 这种查询和match在有些时候是等价的,比如我们查询单个的词hello,那么会和match查询结果一样,但是如果查询"hello world",结果就相差很大,因为这个输入不会进行分词,就是说查询的时候,是查询字段分词结果中是否有"hello world"的字样,而不是查询字段中包含"hello world"的字样。当保存数据"hello world"时,elasticsearch会对字段内容进行分词,"hello world"会被分成hello和world,不存在"hello world",因此这里的查询结果会为空。这也是term查询和match的区别。 3. match_phase match_phase:会对输入做分词,但是需要结果中也包含所有的分词,而且顺序要求一样。以"hello world"为例,要求结果中必须包含hello和world,而且还要求他们是连着的,顺序也是固定的,hello that world不满足,world hello也不满足条件。 4. query_string query_string:和match类似,但是match需要指定字段名,query_string是在所有字段中搜索,范围更广泛。
文档映射
动态映射及规则:
在关系数据库中,需要事先创建数据库,然后在该数据库下创建数据表,并创建表字段、类型、长度、主键等,最后才能基于表插入数据。而Elasticsearch中不需要定义Mapping映射(即关系型数据库的表、字段等),在文档
写入Elasticsearch时,会根据文档字段自动识别类型,这种机制称之为动态映射。
动态映射实例:
2.1 删除原创建的索引 DELETE /es_db 2.2 创建索引 PUT /es_db 2.3 创建文档(ES根据数据类型, 会自动创建映射) PUT /es_db/_doc/1 { "name": "Jack", "sex": 1, "age": 25, "book": "java入门至精通", "address": "广州小蛮腰" } 2.4 获取文档映射 GET /es_db/_mapping
静态映射:
静态映射是在Elasticsearch中也可以事先定义好映射,包含文档的各字段类型、分词器等,这种方式称之为静态映射。
3.1 删除原创建的索引 DELETE /es_db 3.2 创建索引 PUT /es_db 3.3 设置文档映射 PUT /es_db { "mappings":{ "properties":{ "name":{"type":"keyword","index":true,"store":true}, "sex":{"type":"integer","index":true,"store":true}, "age":{"type":"integer","index":true,"store":true}, "book":{"type":"text","index":true,"store":true}, "address":{"type":"text","index":true,"store":true} } } } 3.4 根据静态映射创建文档 PUT /es_db/_doc/1 { "name": "Jack", "sex": 1, "age": 25, "book": "elasticSearch入门至精通", "address": "广州车陂" } 3.5 获取文档映射 GET /es_db/_mapping
核心类型(Core datatype)
字符串:string,string类型包含 text 和 keyword。 text:该类型被用来索引长文本,在创建索引前会将这些文本进行分词,转化为词的组合,建立索引;允许es来检索这些词,text类型不能用来排序和聚合。 keyword:该类型不能分词,可以被用来检索过滤、排序和聚合,keyword类型不可用text进行分词模糊检索。 数值型:long、integer、short、byte、double、float 日期型:date 布尔型:boolean
keyword 与 text 映射类型的区别
将 book 字段设置为 keyword 映射 (只能精准查询, 不能分词查询,能聚合、排序) POST /es_db/_doc/_search { "query": { "term": { "book": "elasticSearch入门至精通" } } }
将 book 字段设置为 text 映射能模糊查询, 能分词查询,不能聚合、排序) POST /es_db/_doc/_search { "query": { "match": { "book": "elasticSearch入门至精通" } } }
创建静态映射时指定text类型的ik分词器
PUT /es_db { "mappings":{ "properties":{ "name":{"type":"keyword","index":true,"store":true}, "sex":{"type":"integer","index":true,"store":true}, "age":{"type":"integer","index":true,"store":true}, "book":{"type":"text","index":true,"store":true,"analyzer":"ik_smart","search_analyzer":"ik_smart"}, "address":{"type":"text","index":true,"store":true} } } }
Elasticsearch乐观并发控制
在数据库领域中,有两种方法来确保并发更新,不会丢失数据: 1、悲观并发控制 这种方法被关系型数据库广泛使用,它假定有变更冲突可能发生,因此阻塞访问资源以防止冲突。 一个典型的例子是读取一行数据之前先将其锁住,确保只有放置锁的线程能够对这行数据进行修改。 2、乐观并发控制 Elasticsearch 中使用的这种方法假定冲突是不可能发生的,并且不会阻塞正在尝试的操作。 然而,如果源数据在读写当中被修改,更新将会失败。应用程序接下来将决定该如何解决冲突。 例如,可以重试更新、使用新的数据
、或者将相关情况报告给用户。
— 再以创建一个文档为例 ES老版本
PUT /db_index/_doc/1 { "name": "Jack", "sex": 1, "age": 25, "book": "Spring Boot 入门到精通", "remark": "hello world" }
— 实现_version乐观锁更新文档
PUT /db_index/_doc/1?version=1 { "name": "Jack", "sex": 1, "age": 25, "book": "Spring Boot 入门到精通", "remark": "hello world" }
ES新版本(7.x)不使用version进行并发版本控制 if_seq_no=版本值&if_primary_term=文档位置
_seq_no:文档版本号,作用同_version
_primary_term:文档所在位置
POST /es_sc/_update/1/?if_seq_no=1&if_primary_term=1 { "doc": { "name": "图灵学院1" } }
今天的文章DSL语言高级查询分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/57045.html