ElasticSearch 学习(一)——安装配置,基本概念与操作
Elastic Search 学习
安装与环境配置
安装包下载
安装环境为macOS,直接去官网进行下载解压安装,但是下载很慢,是外网。
官网下载网址:https://www.elastic.co/cn/downloads/elasticsearch
也可以直接使用brew安装,网上都有教程。
可视化插件选择
直接去chrome商店下载Elastic Search head插件,是一款管理ES的可视化插件。
https://chrome.google.com/webstore/detail/elasticsearch-head/ffmkiejjmecolpfloofpjologoblkegm
相关概念
与MySQL进行对比,两者对应的概念如下
Relational DB | DataBase | Tables | Rows | Columns |
---|---|---|---|---|
Elastic Search | Indices | Types | Documents | Fields |
索引 index
具有相似特征的文档集合。通常会为具有一组共同字段的文档定义一个类型。例如,运营一个博客平台,将所有数据存储到一个索引中,在这个索引中,用户数据是一个类型,博客文章是一个类型,评论数据是一个类型。
字段 field
相当于数据表字段,对文档数据根据不同属性分类标识。
映射 mapping
对处理数据的方式和规则方面做一些限制。
索引基本操作
创建一个索引
PUT /索引名/[类型名]/文档id //类型名会被弃用,默认为_doc
{
"name":"zhangsan",
"age":18
}
创建完索引之后,数据也成功添加,也可以在head中进行数据预览。
此时发现 name age等字段没有设置类型,可以指定字段的类型。
PUT /test1 //此时只有索引,没有后续参数,
{
"mappings":{
"properties":{
"name":{
"type":"text"
},
"age":{
"type":"long"
},
"birthday":{
"type":"date"
}
}
}
}
创建了具体的数据规则。
获取索引信息
通过get请求获取具体的信息,如果文档字段没有指定,ES会默认配置字段类型
GET /test1
通过 GET _cat/ 命令,可以获得ES中的很多信息
修改索引信息
-
直接重新PUT一遍
-
使用POST命令
-
POST /索引名称/类型名称/文档id/_update
删除索引
DELETE /索引名称 //直接删除索引库
DELETE /索引名称/类型名称/文档id //删除索引中的某个文档
文档操作
添加数据
PUT /test/user/1
{
"name":"zhangsan",
"age":18,
"tag":["高","富","帅"]
}
查询数据
GET /test/user/1
更新数据
PUT /test/user/1 //缺失的字段会被置空
{
"name":"wangwu",
"age":18,
"tag":["白","富","美"]
}
//更推荐POST
POST /test/user/1/_update
{
"name":"wangwu",
"age":18,
"tag":["白","富","美"]
}
搜索搜索操作
简单条件查询(所有查询都用GET操作)
GET /test/user/_search?q=name:zhangsan //精确匹配查找name为zhangsan的
查询结果
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": { //hits对象Java中的Hits对象
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.9808291, //最大的得分值
"hits": [
{ //查询出来的具体文档,都可以通过遍历得到
"_index": "test",
"_type": "user",
"_id": "2",
"_score": 0.9808291,
"_source": {
"name": "zhangsan",
"age": 18,
"tag": [
"高",
"富",
"丑"
]
}
}
]
}
}
查询结果中的score代表查询结果的匹配程度高低
复杂查询(排序,分页,高亮,模糊查询,精准查询)
GET /test/user/_search
{
"query":{
"match":{
"name":"%zhangsan%"
}
}
}
指定查询结果展示字段
{
"query":{
"match":{
"name":"%zhangsan%"
}
}
"_source":["name","age"] //只需要name和age
}
按字段排序展示查询结果,并且进行分页
{
"query":{
"match":{
"name":"张" //按张进行匹配,张三,张四,张三丰这种分词后都带张,都可以匹配到
}
},
"sort":[ //sort表示排序,asc按升序查询
{
"age":{
"order":"asc"
}
}
],
"from":0, //从第几条数据开始
"size":2 //每页展示几条数据
}
布尔值查询,可以进行多条件查询
{
"query":{
"bool":{
"must":[
{
"match":{
"name":"张"
}
},
{
"match":{
"age":18
}
}
]
}
}
}
- must (and),所有条件都要符合,where name = “张” and age=18
- should (or),或操作,where name = “张” or age = 18
- must_not (not),否操作,不等于
过滤
{
"query":{
"bool":{
"should":[
{
"match":{
"name":"张"
}
},
{
"match":{
"age":18
}
}
],
"filter":{ //采用filer关键字,与should,must等同级
"range":{
"age":{
"gt":10 //可以进行多个 gt lt lte gte 等同时过滤
}
}
}
}
}
}
- gt大于
- gte大于等于
- lt小于
- lte小于等于
匹配多个条件
{
"query":{
"match":{
"tag":"穷 丑" //直接在搜索关键字字段里用空格隔开,含有 穷 丑 的都能匹配
}
}
}
查询结果
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 7, //总共有7条数据符合,也可以按照匹配分值进行筛选
"relation": "eq"
},
"max_score": 1.6063561, //最匹配的分数为 1.61,按分数高低排列
"hits": [
{
"_index": "test",
"_type": "user",
"_id": "8",
"_score": 1.6063561, //可以看到包含了 穷 丑 两个
"_source": {
"name": "张四",
"age": 21,
"tag": [
"挨",
"穷",
"丑"
]
}
},
{
"_index": "test",
"_type": "user",
"_id": "1",
"_score": 1.2809337, //只包含穷,分数降低
"_source": {
"name": "lisi",
"age": 23,
"tag": [
"矮",
"穷",
"帅"
]
}
},
{
"_index": "test",
"_type": "user",
"_id": "2",
"_score": 0.3254224,
"_source": {
"name": "zhangsan",
"age": 18,
"tag": [
"高",
"富",
"丑"
]
}
},
{
"_index": "test",
"_type": "user",
"_id": "4",
"_score": 0.3254224,
"_source": {
"name": "张三",
"age": 18,
"tag": [
"高",
"富",
"丑"
]
}
},
{
"_index": "test",
"_type": "user",
"_id": "5",
"_score": 0.3254224,
"_source": {
"name": "李四",
"age": 18,
"tag": [
"高",
"富",
"丑"
]
}
},
{
"_index": "test",
"_type": "user",
"_id": "6",
"_score": 0.3254224,
"_source": {
"name": "张三丰",
"age": 26,
"tag": [
"高",
"富",
"丑"
]
}
},
{
"_index": "test",
"_type": "user",
"_id": "7",
"_score": 0.3254224,
"_source": {
"name": "王五",
"age": 21,
"tag": [
"高",
"富",
"丑"
]
}
}
]
}
}
精确查询
term 查询是直接通过倒排索引进行精确查找
match 会使用分词器解析
两个类型 text 和 keyword
text可以被分词器解析;而keyword不能被分词器解析,只能作为整体。以下为示例
//先创建一个testdb作为测试索引
PUT /testdb
{
"mappings":{
"properties":{
"name":{
"type":"text"
},
"desc":{
"type":"keyword"
}
}
}
}
PUT /testdb/_doc/1 //插入两条数据
{
"name":"爱新觉罗张三 name",
"desc":"爱新觉罗张三 desc"
}
PUT /testdb/_doc/2
{
"name":"爱新觉罗张三 name",
"desc":"爱新觉罗张三 desc2"
}
可以先看一下分析器对于 keyword 和 standard的分析区别
GET /_analyze
//body:
{
"analyzer":"keyword",
"text":"爱新觉罗张三 name"
}
//结果:
{
"tokens": [
{
"token": "爱新觉罗张三 name",
"start_offset": 0,
"end_offset": 11,
"type": "word",
"position": 0
}
]
}
//body:
{
"analyzer":"standard",
"text":"爱新觉罗张三 name"
}
//结果:
{
"tokens": [
{
"token": "爱",
"start_offset": 0,
"end_offset": 1,
"type": "<IDEOGRAPHIC>",
"position": 0
},
{
"token": "新",
"start_offset": 1,
"end_offset": 2,
"type": "<IDEOGRAPHIC>",
"position": 1
},
{
"token": "觉",
"start_offset": 2,
"end_offset": 3,
"type": "<IDEOGRAPHIC>",
"position": 2
},
{
"token": "罗",
"start_offset": 3,
"end_offset": 4,
"type": "<IDEOGRAPHIC>",
"position": 3
},
{
"token": "张",
"start_offset": 4,
"end_offset": 5,
"type": "<IDEOGRAPHIC>",
"position": 4
},
{
"token": "三",
"start_offset": 5,
"end_offset": 6,
"type": "<IDEOGRAPHIC>",
"position": 5
},
{
"token": "name",
"start_offset": 7,
"end_offset": 11,
"type": "<ALPHANUM>",
"position": 6
}
]
}
- keyword 不会被分词器分析,会将其当作整体
那么我们对上面添加的 两条数据进行搜索实验:
{
"name":"爱新觉罗张三 name",
"desc":"爱新觉罗张三 desc"
}
{
"name":"爱新觉罗张三 name",
"desc":"爱新觉罗张三 desc2"
}
//其中 name 是 text ,desc 是 keyword
GET /_search
{
"query":{
"term":{
"name":"爱"
}
}
}
//结果:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.18232156,
"hits": [
{
"_index": "testdb",
"_type": "_doc",
"_id": "1",
"_score": 0.18232156,
"_source": {
"name": "爱新觉罗张三 name",
"desc": "爱新觉罗张三 desc"
}
},
{
"_index": "testdb",
"_type": "_doc",
"_id": "2",
"_score": 0.18232156,
"_source": {
"name": "爱新觉罗张三 name",
"desc": "爱新觉罗张三 desc2"
}
}
]
}
}
//name是text格式,“爱新觉罗张三 name” 被分词解析,所以查询任一个中文或英文单词 name 都有结果返回
GET /_search
{
"query":{
"term":{
"desc":"爱"
}
}
}
//结果
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
}
}
//desc是keyword类型,爱新觉罗张三 desc 没有被分词,所以查单个汉字无结果,只有查整体才行,如下:
{
"query":{
"term":{
"desc":"爱新觉罗张三 desc"
}
}
}
多个值匹配的精确查询
先放入两条数据
PUT /testdb/_doc/3
{
"t1":"22",
"t2":"2020-4-6"
}
PUT /testdb/_doc/4
{
"t1":"33",
"t2":"2020-4-7"
}
//进行多个值精确匹配查询
GET /testdb/_search
// 查询 t1 为 22 或 33的
{
"query":{
"bool":{
"should":[
{
"term":
{
"t1":22
}
},
{
"term":
{
"t1":33
}
}
]
}
}
}
高亮关键字
直接查看实现高亮的方法,实际上是为需要高亮的文本添加html标签以修饰
GET /test/user/_search
{
"query":{
"match":{
"name":"张"
}
},
"highlight":{ //配置高亮的一些参数
"pre_tags":"<p class='key' style='color:red'>" , //高亮标签前缀,默认 em
"post_tags":"</p>" , //高亮标签后缀
"fields":{ //高亮的区域
"name":{}
}
}
}
综上,ES可以做到:
- 匹配,按照条件匹配,精确匹配,区间范围匹配,匹配字段过滤
- 多条件查询,高亮查询
下一章将ES集成到SpringBoot中去。
上一篇: Struts小项目二
下一篇: 如何做个气宇轩昂有气量的人