ElasticSearch学习(语法学习 + Java整合)「建议收藏」

ElasticSearch学习(语法学习 + Java整合)「建议收藏」ElasticSearch学习_elasticsearchjava语法

ElasticSearch学习(语法学习

前言
主要还是工作中用到了ES,所以记录一下ES的学习
简单介绍下ES,主要原理就是整合了Lucene,利用了倒排索引的特性,将传入的数据进行分词然后去重再存储。当你输入词语,会根据词语索引到id,再通过id找出所有符合的文档进行呈现,其中可以根据你自己的需求进行对应的分词逻辑,以及打分匹配逻辑,这些就先不说得太多,让我们直接进入ES的语法学习。

前置要求:默认你已经安装好了ElasticSearch以及kibana可视化工具,为了方便描述,接下来会把ElasticSearch简称为ES

一、基础概念

索引 Index

可以理解成MySQL的database的概念,索引的声明必须全部由小写字母组成,对es数据的各种操作都是通过索引来进行的

类型 Type

可以简单的理解成一类东西的定义,在ES7.0之前可以自定义类型,用于更细粒度的数据区分,7.0之后默认_doc类型。与索引概念可以这样理解,我声明了一个手机索引,这个索引下面又区分了很多的手机类型,比如华为,苹果等

映射 Mapping

这里可以与数据库的表结构做对标,声明字段的名称,类型,以及是否参与分词,以及文档内容存储等

字段 Field

就是映射里面的具体的某个字段的含义了

文档 Document

可以理解成MySQL中表的一条记录,一个文档就对应着表里的一条数据

集群 Cluster

ES天然支持分布式存储以及搜索,用来做高可用以及数据备份,多台ES的节点可以组成一个集群共同对外提供服务

节点 Node

集群中的每一个ES实例都可以理解成一个节点

分片

节点会对索引的数据进行分布式存储,就意味着会有分片的产生,而分片中又存在主分片与副本分片的概念,主分片负责读写,副本分片负责数据备份,当然这些分片是分布在多个机器节点,方便用于高可用以及异地容灾的措施

二、增删改查, 基础操作

ES的增删改查是使用的REST Ful风格的语法,可以理解成如下通用模型

操作词 /索引/类型/id
操作词指的就是PUT,POST,GET,DELETE
索引见第一点基础概念
类型见第一点基础概念
Id 这里的id可以自定义,比如你可以使用你的业务id,每一个文档都需要有一个主键Id,如果新增操作不声明id,那么会有ES自动创建一个id作为主键

下面我将会举例一个简单的例子带大家熟悉ES的语法,假设现在有一个需求,公司是做手机售卖的,现在要维护手机的数据,后续会对这批数据进行相应的调整例如新增手机或者删除手机等操作。
那么针对这个需求我们抽象出分别对应ES核心概念的数据

定义索引

首先是手机,这是一种电子产品,将来还有可能是电视机,电脑等。那么我们声明一个手机库来存储对应的手机信息,这个就对应上了ES的索引,起名为tphone

定义类型

手机里面区分很多的品牌,例如华为,苹果,oppo等等。我们给对应的不同品牌的手机挂上对应的类型,例如现在库里就两款手机,一款是oppo手机,声明类型就叫做oppo,一款是苹果手机,声明类型就叫做apple

定义映射与字段

当然每个品牌的手机都有自己的一些属性,我们先简单的定义好对应的属性,接下来以JSON格式定义属性,假设苹果跟oppo目前就这三种属性,其中的每一种属性可以理解成映射当中的一个一个的字段

"memory":"内存""size":"尺寸""pixel""像素"

当然,ES的映射的话目前存在两种方式,一种是动态映射,不用声明字段,直接做插入,ES会自动根据插入的数据类型进行对应的格式转换,转换的逻辑以如下图为准(图待上传)
另外一种是静态映射方式,直接定义字段声明(具体的格式待上传)

有了上述的几种概念以后我们就可以开始正式的接需求了

需求一:仓库新引入华为类型的手机,手机的初始属性与库里已有oppo的属性相同,也是内存,尺寸,像素

新增数据的语法可用PUT与POST,其中PUT与POST之间的差异是,POST在操作时可以不声明ID,这个时候ES会自动的生成ID,不声明ID时,默认为Insert操作,假如声明了ID,且库中已有该ID则会修改操作。而PUT在操作时必须声明ID才能进行操作,至于执行的是新增还是修改,主要取决于库内是否已有当前操作ID

PUT

可用于新增与修改数据,具体的格式如下

//假设库里当前没有ID为1的华为手机,那么如下操作就是insert,否则是做update,update需要注意的一点是会将整个json文档都进行替换,替换成最新put的json文档形式
PUT /tphone/huawei/1
{ 
   
  "memory":"内存""size":"尺寸""pixel""像素"
}

POST

可用于新增与修改数据,(如果类型后跟的是/_search则还可以做查询)具体的格式如下

//假设库里当前没有ID为1的华为手机,那么如下操作就是insert,否则是做update,这里的update只会对提交的相同字段进行修改,而不会影响其他未操作字段
POST /tphone/huawei/1
{ 
   
  "memory":"64G""size":"5.2""pixel""300万"
}

GET

需求2,产品想要看看库里目前已有的华为手机的内容信息

//这里可以查出 huawei类型下的所有华为手机数据
GET /tphone/huawei/_search //相当于 select * from tphone.huawei
//假设我只想看手机内存是64G的华为手机则可以修改成如下语句
GET /tphone/huawei/_search?q=memory:"64G" //相当于 select * from tphone.huawei where memory = “64G”

DELETE

需求3 ,清除ID编码为1的华为手机

DELETE /tphone/huawei/1 //相当于 delete * from tphone.huawei where id = 1 

三、DSL查询

ES其实最重要的目的还是提供了海量数据的快速复杂查询,所有其实光凭第二点描述的普通的查询语句很难表述很复杂的查询,对于这个问题,ES给出了DSL的语句查询模式,可以由开发人员自由组合各种复杂条件查询进行数据筛选

无条件查询

match_all{}

不带条件查询所有数据

GET /tphone/huawei/_search
{ 
   
"query":{ 
   
"match_all":{ 
   }
}
}

模糊查询

GET /tphone/huawei/_search
{ 
   
"query":{ 
   
"match_all":{ 
   }
}
}

match

prefix

regexp(正则表达式)

精确匹配

term

terms

range

exists

ids

match 与 term的那些“坑”

term查询keyword字段

term不会对查询内容分词,keyword字段存储数据的时候也不会对内容分词,所以需要两者完全相同才可查询出来

term查询text字段

term不会对查询内容分词,text字段存储数据的时候会对内容分词,只要term查询的内容在text分词之后有任一一个匹配上了,那么就可以查询出来。例如查询内容是北京,索引存储的内容是北京天安门,然后被分词为了北京跟天安门,那么这个时候是可以查到的,因为北京与北京天安门的分词中是有一个可以匹配上的

match 查询keyword字段

这里稍微特殊点了,经本人测试,match查询keyword时,查询内容必须与keyword完全一致才可以查询到

match 查询text字段

match会对查询内容分词,text类型会对存入数据分词,两者分词之后的词语存在交集则可以被查出来

组合查询

bool

must
filter
must_not
should

constant_score

dis_max

父子文档查询

has_child

has_parent

嵌套文档查询

nested

path
query

ES分组查询

GET 索引名/类型/_search
{ 
   
  "query": { 
   
    "bool": { 
   
      "must": [多条件匹配
        { 
   
          "range": { 
   
            "data": { 
   
              "gte": "2023-10-10T23:00:00",
              "lte": "2023-10-11T00:11:00"
            }
          }
        },
        { 
   
          "term": { 
   
            "name": "小李"
          }
        }
      ]
    }
  },
  "aggs": { 
    分组聚合  类似 group by 一个字段这个字段terms中的field
    "querySumTotalLevelCommission": { 
    自定义命名方便看数据结果
      "terms": { 
     表示分组操作
        "field": "name 分组的字段名"
      },
      "aggs": { 
   
        "group_num": { 
    自定义命名方便看数据结果
          "sum": { 
      分组聚合操作关键字
            "field": "money 要进行分组聚合操作的字段名"
          }
        }
      }
    }
  }
}

以上DSL语句类似MySQL的 
select sum(money) from table where data >= "2023-10-10T23:00:00" and data <= "2023-10-11T00:11:00" and name = "小李"
group by name

范围查找(根据经纬度查找)

小坑,ES的范围查找Geo类的API入参double类型,如果丢入float会出现精度丢失

Script脚本语言查询

查询_source中数组字段phonePhoto的size > 2的文档数据
GET /Phone/_search
{ 
   
  "query": { 
   
    "bool": { 
   
      "filter": [
        { 
   
          "function_score": { 
   
            "query": { 
   
              "match_all": { 
   }
            },
            "functions": [
              { 
   
                "script_score": { 
   
                  "script": { 
   
                    "source": "params._source.containsKey('phonePhoto') && params._source['phonePhoto'] != null && params._source.phonePhoto.size() > 2 ? 2 : 0"
                  }
                }
              }
            ],
            "min_score": 1
          }
        }
      ]
    }
  }
}

四、SpringBoot整合ES进行相关操作

第一步 依赖引入

第二步 客户端注入

第三步 增删改查

Scoll滚动查询

from,to分页查询

五、Index相关操作

删除索引

DELETE /{index}

手动PUT索引

新增索引以及设置Mapping

PUT /{ 
   index}
{ 
   
    "mappings":{ 
   
        "{type}":{ 
   
            "properties":{ 
   
                "id":{ 
   
                    "type":"text",
                    "fields":{ 
   
                        "keyword":{ 
   
                            "type":"keyword",
                            "ignore_above":256
                        }
                    }
                }
            }
        }
    }
}

修改Mapping

PUT /{index}/_mapping/{type}

今天的文章ElasticSearch学习(语法学习 + Java整合)「建议收藏」分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/89052.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注