文章目录
-
-
-
-
- 1、基础
- 2、语法
- 3、基本查询
- 4、高级查询
-
-
-
1、基础
- elasticsearch是一个分布式的全文搜索引擎。
基于Lucene。具有restful的api接口。分布式,高横向扩展能力。 全文检索:分词,在分词库想分词后的关键词。倒排索引。
- 与solr的区别
效率: 单纯的对已有数据进行检索的时候,solr效率更好,高于es;在不断动态添加数据的时候,solr的检索效率会变的低下,而es则没有什么变化。 独立性: Solr利用zookeeper进行分布式管理,而es自身带有分布式系统管理功能。
- 倒排索引也叫反向索引,通俗来讲正向索引是通过key找value,反向索引则是通过value找key。
- type在7中已经被遗弃,ES官方建议 在一个索引库中只存储相同类型的文档。
-
ik分词器
可以去GitHub下载,但是网络问题,可以进入容器,然后切到目录 /usr/share/elasticsearch/bin。之后可以执行./elasticsearch-plugin install http://tomcat01.qfjava.cn:81/elasticsearch-analysis-ik-6.5.4.zip。最后重启一下。
POST _analyze { "analyzer": "ik_max_word", "text": "中国湖北" } # 分为了[中国]和[湖北]
2、语法
- field字段类型,常见如下
字符串类型 text 、 keyword 数值类型 long, integer, short, byte, double, float, half_float, scaled_float 日期类型 date 布尔值类型 boolean 二进制类型 binary 范围类型 integer_range, float_range, long_range, double_range, date_range
-
操作es的restful语法。原本的put修改,post新增,get查询,delete删除
Get:查询
Post:查询# 查询索引信息 http://ip:port/index # 查询文档信息 http://ip:port/index/type/doc_id
Put:创建索引# 查询(查询参数太多的情况,参数可以json格式传参) http://ip:port/index/type/_search # 更新 http://ip:port/index/type/doc_id/_update #创建一个文档(一条数据) http://ip:port/index/type/doc
Delete:删# 创建一个索引,请求体中指定数据结构(即type和字段,settings和mappings) http://ip:port/index # 创建一个文档的属性有哪些,请求体中指定具体信息 http://ip:port/index/type/_mappings #创建一个文档(一条数据) http://ip:port/index/type/doc
# 删除一个索引,对应的数据全部被删除了 http://ip:port/index # 删除一个文档 http://ip:port/index/type/doc_id
-
具体操作
3.1 索引操作
创建一个索引
删除索引# 简单创建一个索引,默认副本数为1,分片数为5 PUT /qsm # 简单创建一个索引,指定副本数和分片数 PUT /qsm1 { "settings": { "number_of_shards": 5 , "number_of_replicas": 1 } } # 若已创建索引,给索引添加数据结构 PUT /qsm/novel/_mappings { "properties":{ "name":{ "type":"text" }, "author":{ "type":"keyword" }, "count":{ "type":"long" }, "onSale":{ "type":"date", "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } } # 创建一个索引并制定数据结构 PUT /book { "settings": { "number_of_shards": 5 , "number_of_replicas": 1 }, "mappings": { "novel":{ "properties":{ "name":{ "type":"text", "analyzer":"ik_max_word" }, "author":{ "type":"keyword" }, "count":{ "type":"long" }, "onSale":{ "type":"date", "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } } } }
查看索引信息# 删除某一个索引 DELETE /qsm # 删除某个前缀的所有索引 DELETE /qsm*
# 查看某个索引 GET /qsm1 # 查看所有索引列表 GET /_cat/indices?v
3.2 文档操作
创建文档
更改文档# 自动创建文档id POST /book/novel { "name":"大秦帝国", "author":"qsm", "count":"10", "onSale":"2020-07-21" } # 手动创建文档id POST /book/novel/1 { "name":"大清帝国", "author":"qsm", "count":"20", "onSale":"2020-07-11" }
删除文档# 覆盖修改,直接相当于已知文档id的手动创建 POST /book/novel/1 { "name":"大清帝国_copy", "author":"qsm", "onSale":"2020-07-11" } # 制定修改,基于doc POST /book/novel/1/_update { "doc": { "name":"大清帝国_copy2" } }
查询文档DELETE /book/novel/qk4vcHMBO6OsUd5sLTc
GET /book/novel/1
- 深分页
ES对from和size之和有限制,不能大于1w
from+size原理:
根据用户输入的词语进行分词
将分词后的分词去分词库中进行检索,得到文档的id
去各个分片中拉去指定的数据
根据数据的score分数进行排序
根据from/limit进行筛选出指定的数据,其他数据舍弃
返回结果
scroll+size原理:
根据用户输入的词语进行分词
将分词后的分词去分词库中进行检索,得到文档的id
将文档的id【放入到一个es上下文中】
根据指定的size去各个分片中拉去指定的数据,并且拿完的文档id会被上下文移除
若需要下一页size的数据,则去es上下文中拿到文档id
接下来跟第四步一样,进行循环
所以scroll没有分数,且不适合实时查询。但是非常快,资源消耗少。
指定scroll查询的时候,会给这个上下文指定过期时间(可以保持)。排序默认是id,也可以手动自定
# from+size POST /sms-logs-index/sms-logs-type/_search { "from": 0, "size": 2, "query": { "wildcard": { "smsContent": { "value": "*荆楚" } } } } # 指定scroll查询 POST /sms-logs-index/sms-logs-type/_search?scroll=2m { "size": 2 , "query": { "match": { "smsContent": "荆楚" } }, "sort": [ { "fee": { "order": "desc" } } ] } #得到数据中"_scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAA0yFndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAANMxZ3REZpa01EYlJONjVZYXUtbExJak5RAAAAAAAADTQWd0RGaWtNRGJSTjY1WWF1LWxMSWpOUQAAAAAAAA02FndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAANNRZ3REZpa01EYlJONjVZYXUtbExJak5R" # scroll下一页查询 POST /_search/scroll { "scroll_id":"DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAA0yFndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAANMxZ3REZpa01EYlJONjVZYXUtbExJak5RAAAAAAAADTQWd0RGaWtNRGJSTjY1WWF1LWxMSWpOUQAAAAAAAA02FndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAANNRZ3REZpa01EYlJONjVZYXUtbExJak5R", "scroll":"2m" } # 删除scroll DELETE /_search/scroll/DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAA4_FndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAAOQRZ3REZpa01EYlJONjVZYXUtbExJak5RAAAAAAAADkAWd0RGaWtNRGJSTjY1WWF1LWxMSWpOUQAAAAAAAA5CFndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAAOQxZ3REZpa01EYlJONjVZYXUtbExJak5R
3、基本查询
查询的基本知识:
若想查询短信信息字段中包含“中国湖北”的数据。则ik分词器会"中国湖北"分为“中国湖北”,“中国”,“湖北”,那么有这三个字段的文档都会匹配查询到,但是会有一个分数,分数最高则会最优质匹配。
前提数据准备
创建索引
PUT /sms-logs-index
{
"settings": {
"number_of_replicas": 1,
"number_of_shards": 5
},
"mappings": {
"sms-logs-type":{
"properties":{
"corpName":{
"type":"keyword"
},
"smsContent":{
"type":"text",
"analyzer":"ik_max_word"
},
"fee":{
"type":"long"
},
"province":{
"type":"keyword"
},
"create":{
"type":"date",
"format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
}
导入数据,可以自己随便编写数据。编写10条左右即可
POST /sms-logs-index/sms-logs-type
{
"corpName":"中国联通",
"smsContent":"欢迎您来到齐鲁大地,祝您平安愉快!拨打漫游地区号+12580订票订房;办理移动业务,请拨10086咨询;中国联通山东公司将竭诚为您服务。",
"fee":"30",
"province":"山东",
"create":"2020-05-19"
}
- match_all查询
查询所有,相当于没有任何查询条件。默认size为10
POST /sms-logs-index/sms-logs-type/_search { "query": { "match_all": {} } }
- match查询
高级查询,不同字段类型采用不同的查询方式
日期或者数字,自动转
keyword,不会分词
text,会自动分词
# match查询 POST /sms-logs-index/sms-logs-type/_search { "query": { "match": { "smsContent": "中国电信" } } } # 注意:中国电信会被分词为:中国移动、中国移、中国、移动。所以只要文档的smsContent字段内容包含了这四个词的,都会被查出来,仅仅是分数会低一下,比如有的内容只出现了[中国] # 现在更新为"smsContent": "齐鲁",则展示结果如下 { "took" : 1, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 1.2005384, "hits" : [ { "_index" : "sms-logs-index", "_type" : "sms-logs-type", "_id" : "PLNYcHMB9IjDRQti4nhj", "_score" : 1.2005384, "_source" : { "corpName" : "中国联通", "smsContent" : "欢迎您来到齐鲁大地,祝您平安愉快!拨打漫游地区号+12580订票订房;办理移动业务,请拨10086咨询;中国联通山东公司将竭诚为您服务。", "fee" : "30", "province" : "山东", "create" : "2020-05-19" } } ] } } # 布尔match查询 POST /sms-logs-index/sms-logs-type/_search { "query": { "match": { "smsContent": { "query": "齐鲁 大地", "operator": "or" } } } }
- mutil_match查询
之前是针对一个field的内容做value检索,mutil_match则是针对多个filed中对该value做检索
#mutil_match查询 POST /sms-logs-index/sms-logs-type/_search { "query": { "multi_match": { "query": "中国热线", "fields": ["corpName","smsContent"] } } } # 中国热线,在corpName不会被分词,在smsContent会被分词
- term查询
代表完全匹配。不会分词,直接去分词库中匹配内容,所以很适合string文本类型为keyword类型的。
以“奋斗的时代”为例:使用ik分词器分为:奋斗,奋,斗,时代。但是term和terms是不分词的,所以ik分词器中是没有“奋斗的时代”这5个字的词语,所以就查询不到。即使后面正在的完整句子有改5个字的词语。
POST /sms-logs-index/sms-logs-type/_search { "from": 0, "size": 20, "query": { "term": { "corpName": { "value": "中国移动" } } } }
- terms查询
机制跟term一致,不过它可以针对一个field字段的内容包含多个值的时候使用。如同sql中or。省份为北京或者上海或者辽宁
POST /sms-logs-index/sms-logs-type/_search { "from": 0, "size": 20, "query": { "terms": { "province": [ "辽宁", "山东" ] } } }
- id查询
直接根据文档的id获取某一条数据
GET /sms-logs-index/sms-logs-type/PrNjcHMB9IjDRQtiY3hb
- ids查询
根据多个id获取
POST /sms-logs-index/sms-logs-type/_search { "query": { "ids": { "values": ["NrNWcHMB9IjDRQtiK3iX","PrNjcHMB9IjDRQtiY3hb"] } } }
- fuzzy模糊纠正查询
根据查询词语,大概的去查询数据。注意是大概,也就是很不稳定,因为查询词语可以是有错别字等。比如,想去匹配盒马鲜生,输入河马先生也是有可能查询的到。但是差距太大,则也有可能差不多。所以稳定性差
# 改为中国一动可以查询的到,但是改为中国yi动则查询不到 POST /sms-logs-index/sms-logs-type/_search { "query": { "fuzzy": { "corpName": { "value": "中国一动" } } } } # 前面3个字符一样,这样的话就查询不到了 POST /sms-logs-index/sms-logs-type/_search { "query": { "fuzzy": { "corpName": { "value": "中国一动", "prefix_length": 3 } } } }
- prefix前缀查询
可以根据想搜索字段的前面的一部分去搜索。不仅仅适合text类型,也适用于keyword关键字类型的。都能查出
POST /sms-logs-index/sms-logs-type/_search { "query": { "prefix": { "smsContent": { "value": "尊敬" } } } }
- wildcard通配查询
跟mysql的like查询类似。通配符*为多个未知字符,?为一个字符。
非常消耗资源
POST /sms-logs-index/sms-logs-type/_search { "query": { "wildcard": { "corpName": { "value": "??电信" } } } } POST /sms-logs-index/sms-logs-type/_search { "query": { "wildcard": { "smsContent": { "value": "*荆楚" } } } }
- regexp正则查询
正则匹配的查询
以上fuzzy、prefix、wildcard和regexp查询效率低,耗费资源的。前缀匹配是优于wildcard和regexp。
POST /sms-logs-index/sms-logs-type/_search { "query": { "regexp": { "corpName": "中国联通[0-9]{2}" } } } # 有一个数据 "corpName" : "中国联通12"。所以该正则可以查到数据
- rang数字范围查询
范文查询,针对数字
POST /sms-logs-index/sms-logs-type/_search { "query": { "range": { "fee": { "gte": 100, "lte": 200 } } } }
4、高级查询
- delete_by_query
根据match或者term等基本查询操作查询到的数据进行删除
POST /sms-logs-index/sms-logs-type/_delete_by_query { "query":{ "range":{ "fee":{ "gte": 3000 } } } } # 结果如下deleted为2,删除了2条 { "took" : 32, "timed_out" : false, "total" : 2, "deleted" : 2, "batches" : 1, "version_conflicts" : 0, "noops" : 0, "retries" : { "bulk" : 0, "search" : 0 }, "throttled_millis" : 0, "requests_per_second" : -1.0, "throttled_until_millis" : 0, "failures" : [ ] }
- bool查询
过滤器查询,将多个查询调教,以一定逻辑操作组合到一起
must:相当于都符合,and
must_not:相当于都不符合,not
should:相当于或者,or
filter:不计算分数,对经常过滤的数据进行缓存
# 省份为湖北或者北京 POST /sms-logs-index/sms-logs-type/_search { "query": { "bool": { "should": [ { "term": { "province": { "value": "湖北" } } }, { "term": { "province": { "value": "北京" } } } ] } } } #公司不是中国移动 #短信内容包含中国和大地 POST /sms-logs-index/sms-logs-type/_search { "query": { "bool": { "must_not": [ { "term": { "corpName": { "value": "中国移动" } } } ], "must": [ { "match": { "smsContent": "中国" } }, { "match": { "smsContent": "大地" } } ] } } } # 【注意】must和should混合使用的时候,发现should不起作用了。这个时候可以根据严谨的数据逻辑编写查询语句 # filter查询 POST /sms-logs-index/sms-logs-type/_search { "query": { "bool": { "filter": [ { "term":{ "corpName": "中国移动" } }, { "range":{ "fee":{ "gte": 3000 } } } ] } } }
- filter查询
query:查询到的文档的匹配度会得到分数,并且排序,不会缓存,适合实时查询
filter:查询到的文档不会计算分数,而是会对经常被过滤的数据进行缓存
# filter查询 POST /sms-logs-index/sms-logs-type/_search { "query": { "bool": { "filter": [ { "term":{ "corpName": "中国移动" } }, { "range":{ "fee":{ "gte": 3000 } } } ] } } }
- boosting查询
提升分数查询。默认按照分数,但是有时候想改变一下排序权重
通过将文档原本的_score和negative_boost参数进行相乘来得到新的_score。
positive查询:匹配到了positive查询的文档才会被包含到结果集中
negative查询:满足positive之后,又满足negative,则匹配的文档会被降低其相关度
negative_boost系数小于1.0
# 正常查询 POST /sms-logs-index/sms-logs-type/_search { "query": { "match": { "smsContent": "北京" } } } #boosting查询 #短信内容有北京的,公司为中国移动的,则降低其分数 POST /sms-logs-index/sms-logs-type/_search { "query": { "boosting": { "positive": { "match": { "smsContent": "北京" } }, "negative": { "match": { "corpName": "中国移动" } }, "negative_boost": 0.2 } } }
- 高亮查询
查询的语句会被高亮显示。
高亮的数据不会影响原来的数据,而是单独将filed对应的数据以高亮返回
POST /sms-logs-index/sms-logs-type/_search { "query": { "term": { "smsContent": "荆楚" } } , "highlight": { "fields": { "smsContent": { "pre_tags": "<font color='red'>", "post_tags": "</font>", "fragment_size": 10 } } } } #结果 { "_index" : "sms-logs-index", "_type" : "sms-logs-type", "_id" : "PbNicHMB9IjDRQti4Hgh", "_score" : 1.1748445, "_source" : { "corpName" : "中国电信", "smsContent" : "欢迎您来到荆楚大地大地,祝您平安愉快!拨打漫游地区号+12580订票订房;办理移动业务,请拨10086咨询;中国电信荆州公司将竭诚为您服务。", "fee" : "30", "province" : "湖北", "create" : "2020-05-19" }, "highlight" : { "smsContent" : [ "欢迎您来到<font color='red'>荆楚</font>大地大地" ] } }
- 聚合查询
使用aggs。在查询数据的最后单独展示
1、去重计数cardinality
2、范围统计range。数值range,时间范围date_range,ip范围ip_date。from包含,to不包含。
3、统计查询extended_stats,最大值,最小值,平均值等
- 经纬度查询
根据地点在地图的坐标,来确定一个范围。看某个点在不在范围中。字段filed的类型为geo_point。
确定范围有,以直线确定一个圆;以2个点确定一个矩形;多个点连接为多边形来确定一个范围。
自此es基础版笔记记录完毕,若想查看es高级功能和原理,请点击es进阶版笔记(待续)
若想安装es和kibana可以移步至docker安装es和kibana——非常简单
【暂完】
正在去BAT的路上修行