当前位置:   article > 正文

ElasticSearch语法

ElasticSearch语法

Elasticsearch 概念

入门学习:

  • Index索引=>MySQL 里的表(table)
  • 建表、增删改查(查询需要花费的学习时间最多)
  • 用客户端去调用 ElasticSearch(3 种)
  • 语法:SQL、代码的方法(4 种语法)

ES 相比于 MySQL,能够自动帮我们做分词,能够非常高效、灵活地查询内容。

索引(倒排索引)

正向索引:理解为书籍的目录,可以快速帮你找到对应的内容(怎么根据页码找到文章)

倒排索引:怎么根据内容找到文章

文章 A: 你好,我是 rapper

文章 B: 苏麟暴打小杨科

切词 :

id
你好文章 A

文章 A
rapper文章 A
苏麟文章 B
暴打文章 B
杨科文章 B

用户搜索 : 苏麟杨科

ES切词 : 苏麟 , 杨科

然后去倒排索引表找对应的文章

ES 的几种调用方式

1) restful api 调用(http 请求)

GET请求localhost:9200

curl 可以模拟发送请求: curl -XGET"localhost:9200/?pretty

ES 的启动端口

1.9200:给外部用户(给客户端调用)的端口

2.9300:给 ES 集群内部通信的(外部调用不了的)

2) kibana devtools

自由地对 ES 进行操作(本质也是 restful api)
devtools 不建议生产环境使用

3)客户端调用

java 客户端、go 客户端等。

参考文档 : Getting started | Elasticsearch Java API Client [7.17] | Elastic

ES 的语法

DSL

json 格式,好理解;和 http 请求最兼容,应用最广

建表,插入数据  (文档就是MySQL里的表,映射就是MySQL里的字段)

post 就相当于表名  , title 和 content 就相当于字段

  1. POST post/_doc
  2. {
  3. "title":"苏麟",
  4. "content":"苏麟暴打小杨科"
  5. }

successful 就代表存入成功了 

查询

DSL (不要背) : Query DSL | Elasticsearch Guide [7.17] | Elastic

查询全部 

  1. GET post/_search
  2. {
  3. "query": {
  4. "match_all": {}
  5. }
  6. }

根据 id 查询 

GET post/_doc/UBHryo0B5ErW0HhSBc0q

修改

根据 id 修改

  1. POST post/_doc/UBHryo0B5ErW0HhSBc0q
  2. {
  3. "title":"杨科",
  4. "content":"杨科委委屈屈!"
  5. }

删除

根据文档删除

DELETE post


EQL

专门查询 ECS 文档(标准指标文档)的数据的语法,更加规范,但只适用于特定场景(比如事件流)

文档 : EQL search | Elasticsearch Guide [7.17] | Elastic

建表,插入

  1. POST post_my/_doc
  2. {
  3. "title": "苏麟爱看美女",
  4. "@timestamp": "2099-05-06T16:21:15.000Z",
  5. "event": {
  6. "original": "192.0.2.42 - - [06/May/2099:16:21:15 +0000] \"GET /images/bg.jpg HTTP/1.0\" 200 24736"
  7. }
  8. }

查询

  1. GET post_my/_search
  2. {
  3. "query": {
  4. "match_all": { }
  5. },
  6. "sort": [
  7. {
  8. "@timestamp": "desc"
  9. }
  10. ]
  11. }

SQL

文档 : Getting Started with SQL | Elasticsearch Guide [7.17] | Elastic

查询

  1. POST /_sql?format=txt
  2. {
  3. "query": "SELECT * FROM post "
  4. }

Painless Scripting language

编程式取值,更灵活,但是学习成本高

Mapping

文档 : Explicit mapping | Elasticsearch Guide [7.17] | Elastic

可以理解为数据库的表结构,有哪些字段、字段类型,

ES 支持动态 mapping,表结构可以动态改变,而不像 MySQL 一样必须手动建表,没有的字段就不能插入。

  1. GET user/_mapping
  2. PUT /user
  3. {
  4. "mappings": {
  5. "properties": {
  6. "age": { "type": "integer" },
  7. "email": { "type": "keyword" },
  8. "name": { "type": "text" }
  9. }
  10. }
  11. }

分词器

指定了分词的规则。

内置分词器 : Built-in analyzer reference | Elasticsearch Guide [7.17] | Elastic

示例 : 

空格分词器: whitespace,结果The、quick、brown、fox.

  1. POST _analyze
  2. {
  3. "analyzer": "whitespace",
  4. "text": "The quick brown fox."
  5. }

标准分词规则,结果:is、this、deja、vu

  1. POST _analyze
  2. {
  3. "tokenizer": "standard",
  4. "filter": [ "lowercase", "asciifolding" ],
  5. "text": "Is this déja vu?"
  6. }

关键词分词器:就是不分词,整句话当作专业术语

  1. GET _analyze
  2. {
  3. "analyzer": "keyword",
  4. "text": "Is this sl?"
  5. }

打分机制

比如有3条内容:

1.苏麟是gay

2.苏麟暴打小杨科

3.小杨科

用户搜索:

1.杨科,第三条分数最高,因为第三条匹配了关键词,而且更短(匹配比例更大)

2.苏麟  => 苏麟是gay => 苏麟暴打小杨科 , 排序结果 1  2

参考文章 : Controlling Relevance | Elasticsearch: The Definitive Guide [master] | Elastic

Java 操作 ES

3 种方式:

1) ES 官方的 Java API

文章 : Introduction | Elasticsearch Java API Client [7.17] | Elastic

快速开始 : Connecting | Elasticsearch Java API Client [7.17] | Elastic

2) ES 以前的官方 Java APl,HighLevelRestclient(已废弃,不建议用)

3) Spring Data Elasticsearch(推荐)

spring-data 系列:spring 提供的操作数据的框架

spring-data-redis:操作 redis 的-套方法

spring-data-mongodb:操作 mongodb 的一套方法

spring-data-elasticsearch:操作 elasticsearch 的一套方法

...

建表结构:

aliases 起别名

  1. PUT post_v1
  2. {
  3. "aliases": {
  4. "post": {}
  5. },
  6. "mappings": {
  7. "properties": {
  8. "title": {
  9. "type": "text",
  10. "analyzer": "ik_max_word",
  11. "search_analyzer": "ik_smart",
  12. "fields": {
  13. "keyword": {
  14. "type": "keyword",
  15. "ignore_above": 256
  16. }
  17. }
  18. },
  19. "content": {
  20. "type": "text",
  21. "analyzer": "ik_max_word",
  22. "search_analyzer": "ik_smart",
  23. "fields": {
  24. "keyword": {
  25. "type": "keyword",
  26. "ignore_above": 256
  27. }
  28. }
  29. },
  30. "tags": {
  31. "type": "keyword"
  32. },
  33. "thumbNum": {
  34. "type": "long"
  35. },
  36. "favourNum": {
  37. "type": "long"
  38. },
  39. "userId": {
  40. "type": "keyword"
  41. },
  42. "createTime": {
  43. "type": "date"
  44. },
  45. "updateTime": {
  46. "type": "date"
  47. },
  48. "isDelete": {
  49. "type": "keyword"
  50. }
  51. }
  52. }
  53. }

增删改查

第一种方式: ElasticsearchRepository<xxxx, Long>,默认提供了简单的增删改查,多用于可预期的、相对没那么复杂的查询、自定义查询,返回结果相对简单直接。

有一些现成的方法可以使用

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by FernFlower decompiler)
  4. //
  5. package org.springframework.data.repository;
  6. import java.util.Optional;
  7. @NoRepositoryBean
  8. public interface CrudRepository<T, ID> extends Repository<T, ID> {
  9. <S extends T> S save(S entity);
  10. <S extends T> Iterable<S> saveAll(Iterable<S> entities);
  11. Optional<T> findById(ID id);
  12. boolean existsById(ID id);
  13. Iterable<T> findAll();
  14. Iterable<T> findAllById(Iterable<ID> ids);
  15. long count();
  16. void deleteById(ID id);
  17. void delete(T entity);
  18. void deleteAllById(Iterable<? extends ID> ids);
  19. void deleteAll(Iterable<? extends T> entities);
  20. void deleteAll();
  21. }

第二种方式: Spring 默认给我们提供的操作 es 的客户端对象 ElasticsearchRestTemplate,也提供了增删改查它的增删改查更灵活,适用于更复杂的操作,返回结果更完整,但需要自己解析。

准备工作

  1. package com.yupi.springbootinit.model.dto.post;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.json.JSONUtil;
  4. import com.yupi.springbootinit.model.entity.Post;
  5. import lombok.Data;
  6. import org.apache.commons.lang3.StringUtils;
  7. import org.springframework.beans.BeanUtils;
  8. import org.springframework.data.annotation.Id;
  9. import org.springframework.data.elasticsearch.annotations.Document;
  10. import org.springframework.data.elasticsearch.annotations.Field;
  11. import org.springframework.data.elasticsearch.annotations.FieldType;
  12. import java.io.Serializable;
  13. import java.util.Date;
  14. import java.util.List;
  15. /**
  16. * 帖子 ES 包装类
  17. *
  18. **/
  19. @Document(indexName = "post")
  20. @Data
  21. public class PostEsDTO implements Serializable {
  22. private static final String DATE_TIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
  23. /**
  24. * id
  25. */
  26. @Id
  27. private Long id;
  28. /**
  29. * 标题
  30. */
  31. private String title;
  32. /**
  33. * 内容
  34. */
  35. private String content;
  36. /**
  37. * 标签列表
  38. */
  39. private List<String> tags;
  40. /**
  41. * 创建用户 id
  42. */
  43. private Long userId;
  44. /**
  45. * 创建时间
  46. */
  47. @Field(index = false, store = true, type = FieldType.Date, format = {}, pattern = DATE_TIME_PATTERN)
  48. private Date createTime;
  49. /**
  50. * 更新时间
  51. */
  52. @Field(index = false, store = true, type = FieldType.Date, format = {}, pattern = DATE_TIME_PATTERN)
  53. private Date updateTime;
  54. /**
  55. * 是否删除
  56. */
  57. private Integer isDelete;
  58. private static final long serialVersionUID = 1L;
  59. /**
  60. * 对象转包装类
  61. *
  62. * @param post
  63. * @return
  64. */
  65. public static PostEsDTO objToDto(Post post) {
  66. if (post == null) {
  67. return null;
  68. }
  69. PostEsDTO postEsDTO = new PostEsDTO();
  70. BeanUtils.copyProperties(post, postEsDTO);
  71. String tagsStr = post.getTags();
  72. if (StringUtils.isNotBlank(tagsStr)) {
  73. postEsDTO.setTags(JSONUtil.toList(tagsStr, String.class));
  74. }
  75. return postEsDTO;
  76. }
  77. /**
  78. * 包装类转对象
  79. *
  80. * @param postEsDTO
  81. * @return
  82. */
  83. public static Post dtoToObj(PostEsDTO postEsDTO) {
  84. if (postEsDTO == null) {
  85. return null;
  86. }
  87. Post post = new Post();
  88. BeanUtils.copyProperties(postEsDTO, post);
  89. List<String> tagList = postEsDTO.getTags();
  90. if (CollUtil.isNotEmpty(tagList)) {
  91. post.setTags(JSONUtil.toJsonStr(tagList));
  92. }
  93. return post;
  94. }
  95. }
  1. public interface PostEsDao extends ElasticsearchRepository<PostEsDTO, Long> {
  2. }
  1. @Resource
  2. private PostEsDao postEsDao;

测试 

  1. @Test
  2. void testAdd() {
  3. PostEsDTO postEsDTO = new PostEsDTO();
  4. postEsDTO.setId(1L);
  5. postEsDTO.setTitle("苏麟");
  6. postEsDTO.setContent("风雨交加的夜晚,苏麟暴打小杨科,小杨科奄奄一息");
  7. postEsDTO.setTags(Arrays.asList("苏麟", "杨科","暴打"));
  8. postEsDTO.setUserId(1L);
  9. postEsDTO.setCreateTime(new Date());
  10. postEsDTO.setUpdateTime(new Date());
  11. postEsDTO.setIsDelete(0);
  12. postEsDao.save(postEsDTO);
  13. System.out.println(postEsDTO.getId());
  14. }

DSL  查询结果

查询结果

  1. @Test
  2. void testFindById() {
  3. Optional<PostEsDTO> postEsDTO = postEsDao.findById(1L);
  4. System.out.println(postEsDTO);
  5. }

DSL 查询转换 Java 代码查询

DSL 查询 

文档 : Query and filter context | Elasticsearch Guide [7.17] | Elastic

文档 : Boolean query | Elasticsearch Guide [7.17] | Elastic

  1. GET post/_search
  2. {
  3. "query": {
  4. "bool": { //组合条件
  5. "must": [ //必须满足
  6. { "match": { "title": "苏麟" }}, //match 模糊查询
  7. { "match": { "content": "苏麟" }}
  8. ],
  9. "filter": [ //过滤
  10. { "term": { "status": "published" }}, //term 精确查询
  11. { "range": { "publish_date": { "gte": "2015-01-01" }}} //范围查询
  12. ]
  13. }
  14. }
  15. }
  1. GET post/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. { "match": { "title": "苏麟" }},
  7. { "match": { "content": "苏麟" }}
  8. ]
  9. }
  10. }
  11. }

wildcard 模糊查询
regexp 正则匹配查询

查询结果中,score 代表匹配分数
建议先测试 DSL、再翻译成 Java

  1. POST _search
  2. {
  3. "query": {
  4. "bool" : {
  5. "must" : {
  6. "term" : { "user.id" : "kimchy" }
  7. },
  8. "filter": {
  9. "term" : { "tags" : "production" }
  10. },
  11. "must_not" : {
  12. "range" : {
  13. "age" : { "gte" : 10, "lte" : 20 }
  14. }
  15. },
  16. "should" : [
  17. { "term" : { "tags" : "env1" } },
  18. { "term" : { "tags" : "deployed" } }
  19. ],
  20. "minimum_should_match" : 1,
  21. "boost" : 1.0
  22. }
  23. }
  24. }

这期就到这里 , 下期见 !

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/141748
推荐阅读
相关标签
  

闽ICP备14008679号