基于ElasticSearch6.*的基本操作,只涉及基本使用,不包含集群搭建、部署等
扩展后期可能会单独发一些,欢迎关注
请求地址 http://localhost:9200/name/ #name为创建索引的名字
PUT /name #put请求,右面是名字
{
"settings": {
"index": {
"number_of_shards": "2", #分片书
"number_of_replicas": "0" #副本数
}
}
}
请求地址 http://localhost:9200/name/
DELETE /name #DELETE请求,右面是名字
http://localhost:9200/索引/类型/id
例:http://localhost:9200/test/user/0001
POST /name/type/id
body:
{
"id":1,
"name":"李华",
"age":20,
"sex":"男"
}
http://localhost:9200/test/user/0001
PUT /name/type/id
body:
{
"id":1,
"name":"李华1",
"age":20,
"sex":"男"
}
直接覆盖
http://localhost:9200/test/user/0001/_update #注意这里加了_update
POST /name/type/id
body:
{
"doc":{
"sex":"男"
}
}
DELETE /name/type/id
直接执行
http://localhost:9200/test/user/0001/
GET /name/type/id
获取多条
http://localhost:9200/test/user/_search #默认返回10条,多了需要做分页
按需索引
http://localhost:9200/test/user/_search?q=age:20
http://localhost:9200/test/user/_search
POST /name/type/_search
{
"query":{
"match":{
"age":20
}
}
}
http://localhost:9200/test/user/_search
POST /name/type/_search
{
"query": {
#查找
"bool": {
"filter": {
#过滤
"range": {
#范围
"age": {
#age属性
"gt": 30 #大于30
}
}
},
"must": {
#满足
"match": {
"sex": "男"
}
}
}
}
}
符号标识 代表含义
gte 大于或等于
gt 大于
lte 小于或等于
lt 小于
http://localhost:9200/test/user/_search
POST /name/type/_search
{
"query":{
"match":{
"name":"张三 李四"
}
}
}
http://localhost:9200/test/user/_search
POST /name/type/_search
{
"query": {
"match": {
"name": "李华1"
}
},
"highlight": {
"fields": {
"name": {
}
}
}
}
会多返回这么一段
"highlight":{
"name":[
"汪京1"
]
}
http://localhost:9200/test/user/_search
POST /name/type/_search
以年龄聚合
{
"aggs": {
"all_interests": {
"terms": {
"field": "age"
}
}
}
}
多返回了
{
"aggregations": {
"all_interests": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 18,
"doc_count": 1
},
{
"key": 20,
"doc_count": 1
}
]
}
}
}
http://localhost:9200/test/user/0001?_source=id,name
GET /name/type/id?_source=id,name
返回
{
"_index": "test",
"_type": "user",
"_id": "0001",
"_version": 1,
"found": true,
"_source": {
"name": "李华1",
"id": 1
}
}
加_source去掉头
http://localhost:9200/test/user/0001/_source?_source=id,name
{
"name": "李华1",
"id": 1
}
判断文档是否存在
http://localhost:9200/test/user/0002
HEAD /name/type/id
批量操作
http://localhost:9200/test/user/_mget #批量获得
POST /name/type/_mget
{
"ids":["id1","id2"]
}
返回结果
{
"docs": [
{
"_index": "test",
"_type": "user",
"_id": "0001",
"_version": 1,
"found": true,
"_source": {
"id": 1,
"name": "李华1",
"age": 20,
"sex": "男"
}
},
{
"_index": "test",
"_type": "user",
"_id": "1111",
"found": false #没找到
}
]
}
http://localhost:9200/test/user/_bulk
POST /name/type/_bulk
创建
{
"create": {
"_index": "test", "_type": "user", "_id": "0003"}}
{
"id": "0003", "name": "李华3", "age": 23, "sex": "男"}
{
"create": {
"_index": "test", "_type": "user", "_id": "0004"}}
{
"id": "0004", "name": "李华4", "age": 23, "sex": "女"}
{
"create": {
"_index": "test", "_type": "user", "_id": "0005"}}
{
"id": "0005", "name": "李华5", "age": 23, "sex": "男"} #这必须要来个回车
删除
{
"delete": {
"_index": "test", "_type": "user", "_id": "0005"}}
性能优化,批量操作数量不是越多越好,操作任务会被放在内存中,请妥善寻找最佳大小
size:结果数,默认10
from:跳过开始的结果数,默认为0 #就是跳过多少个后开始查
就是从那条开始读,读几条实现分页
GET /_search?size=5 查5条数据
GET /_search?size=5&from=5 跳过5条,就是第二页
GET /_search?size=5&from=10 跳过10条,就是第三页
类型 | 表示的数据 |
---|---|
String | string,text,keyword |
Whole number | byte,short,integer,long |
Floating point | float,double |
Boolean | boolean |
Date | date |
Text:会分词,然后进行索引
支持模糊、精确查询
不支持聚合
keyword:不进行分词,直接索引
支持模糊、精确查询
支持聚合
请求地址 http://localhost:9200/name/ #name为创建索引的名字
PUT /name #put请求,右面是名字
{
"settings": {
"index": {
"number_of_shards": "2", #分片书
"number_of_replicas": "0" #副本数
}
},
"mappings": {
"person": {
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "integer"
},
"mail": {
"type": "keyword"
},
"hobby": {
"type": "text"
"analyzer": "ik_max_word" #指定分词器
}
}
}
}
}
GET /name/_mapping
{
"test1": {
"mappings": {
"person": {
"properties": {
"age": {
"type": "integer"
},
"hobby": {
"type": "text"
},
"mail": {
"type": "keyword"
},
"name": {
"type": "text"
}
}
}
}
}
}
#term 精确查询
主要用于精确匹配那些值,比如数字,日期,布尔值或not_analyzed的字符串(未经分析的文本数据类型)
POST /name/type/_search
{
"query":{
"term":{
"age":18
}
}
}
#terms 多匹配精确查询
terms跟term有点类似,单terms允许指定多个匹配条件,如果某个字段指定了多个值,那么文档需要一起做匹配
{
"term":{
"tag":["search","full_text","nosql"]
}
}
{
"query":{
"terms":{
"age":[18,20] #注意:匹配而不是范围查询!
}
}
}
#range 范围查询
范围查询
{
"query":{
"range":{
"age":{
"gte:17", # 大于等于17
"lt":30 # 小于30
}
}
}
}
gte:大于等于
gt:大于
lte:小于等于
lt:小于
boost:设置查询的推动值(boost),默认为1.0
`时间范围查询`
#exists 存在字段查询
exists查询可以用于查询文档中是否包含指定字段或没有某个`字段`,类似于sql语句中的is_null条件
POST localhost/_search #不加索引名称也可以
{
"query":{
"exists":{
#必须包含某个字段
"field": "age"
}
}
}
#match 标准查询
match查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到他,
如果你使用match查询一个全文本字段,它会在真正查询之前用分析器match一下查询字段
如果你传入的是数字布尔日期或者not_analyzed字符串时,它将为你提供准确查询
POST /_search #可以指定索引
{
"query":{
"match":{
"hobby":"fate"
}
}
}
#bool 布尔查询
POST /_search
bool查询可以用来合并多个条件查询结果的布尔逻辑,他包含以下操作符:
`must`:多个查询条件的完全匹配 相当于 and
`must_not`:多个查询条件的相反匹配 相当于 not
`should`:至少有一个查询条件匹配 相当于 or
{
"query": {
"bool": {
"must": {
"term": {
"age": "18" #满足年龄是18就可以返回
}
},
"must_not": {
"term": {
"name": "李华" #名字不能是李华 绝对不能是李华
}
},
"should": [{
"match": {
"hobby": "fate" ,#爱好是fate分词查询
}
},
{
"match": {
"mail": "[email protected]" #邮箱是这个 两个满足一个就行
}
}
]
}
}
}
单独说一下时间的range查询
日期字段的范围
当范围查询运行在日期类型的字段上时,可以通过日期数学指定范围。
GET _search { "query": { "range" : { "date" : { "gte" : "now-1d/d", "lt" : "now/d" } } } } 1234567891011
日期数学与舍入
当使用日期数学将日期舍入到最近的天、月、小时等时,舍入后的日期依赖于范围的边界是否被包含。向上舍入移动到舍入范围的最后一毫秒,向下舍入移动到舍入范围的第一毫秒。
- gt:大于舍入的日期,2014-11-18||/M变为2014-11-30T23:59:59.999,即不包括整个月。
- gte:大于等于舍入的日期,2014-11-18||/M变为2014-11-01,即包括整个月。
- lt:小于舍入的日期,204-11-18||/M变为2014-11-01,即不包括整个月。
- lte:小于等于舍入的日期,2014-11-18||/M变为2014-11-30T23:59:59.999,即包含整个月。
范围查询中的日期格式
默认使用设置在日期字段中的format参数解析格式化日期,但是,此参数可以通过在范围查询中设置format参数来进行覆盖。GET _search { "query": { "range" : { "born" : { "gte": "01/01/2012", "lte": "2013", "format": "dd/MM/yyyy||yyyy" } } } } 123456789101112
范围查询中的时区
通过在日期值中指定时区或使用time_zone参数指定时区,可以转换日期时区。GET _search { "query": { "range" : { "timestamp" : { "gte": "2015-01-01 00:00:00", "lte": "now", "time_zone": "+01:00" } } } } 123456789101112
note:gte参数的日期值将会被转化为2014-12-31T23:00:00 UTC
note:now不会被time_zone参数影响(日期必须存储为UTC)参考:https://blog.csdn.net/qq_32165041/article/details/83714203
过滤查询
#查询年龄未18岁user 类型通过restful指定
POST /name/type/_search
{
"query":{
"bool":{
"filter":{
"term":{
"age":18
}
}
}
}
}
#注意:
- 一条查询语句会计算每个文档与查询语句之间的相关性,并给出评分,然后按评分排序
- 过滤查询会缓存数据,一般过滤查询性能要高于普通查询
- `建议:做精确查询的时候尽量使用过滤查询,因为过滤查询可以缓存数据`
#指定分词器进行分词
POST /_analyze
{
"analyze":"standard",
"text":"fate动漫"
}
`返回`
{
"tokens":[
{
"token": "fate",
"start_offset": 0,
"end_offset": 4,
"type": "" ,
"position": 0
},
{
"token": "动",
"start_offset": 4,
"end_offset": 5,
"type": "" ,
"position": 1
},
{
"token": "漫",
"start_offset": 5,
"end_offset": 6,
"type": "" ,
"position": 2
}
]
}
`在做一个测试` #指定索引库,指定字段的text
POST /name/_analyze
{
"analyzer":"standard",
"field":"hobby",
"text":"fate动漫"
}
#使用ik分词器分词 涉及ik分词器的安装,自行百度
POST /_analyze
{
"analyzer":"ik_max_word",
"text":"中华人民共和国"
}
结果
tokens":[
{
"token": "中华人民共和国", "start_offset": 0, "end_offset": 7, "type": "CN_WORD",…},
{
"token": "中华人民", "start_offset": 0, "end_offset": 4, "type": "CN_WORD",…},
{
"token": "中华", "start_offset": 0, "end_offset": 2, "type": "CN_WORD",…},
{
"token": "华人", "start_offset": 1, "end_offset": 3, "type": "CN_WORD",…},
{
"token": "人民共和国", "start_offset": 2, "end_offset": 7, "type": "CN_WORD",…},
{
"token": "人民", "start_offset": 2, "end_offset": 4, "type": "CN_WORD",…},
{
"token": "共和国", "start_offset": 4, "end_offset": 7, "type": "CN_WORD",…},
{
"token": "共和", "start_offset": 4, "end_offset": 6, "type": "CN_WORD",…},
{
"token": "国", "start_offset": 6, "end_offset": 7, "type": "CN_CHAR",…}
]
- 相关性
- 分词
测试步骤:
1.创建索引,指定text类型
2.创建文档 #较占篇幅,自行百度或者看上面的批量操作示例
3.单词搜索
POST /name/type/_search
{
"query":{
"match":{
"hobby":"鸡蛋,饭" #可以单个也可以多个,用,号分割,满足其中一个就行
}
},
"highlight":{
#高亮
"fields":{
"hobby":{
}
}
}
}
4.多词搜索
POST /name/type/_search
{
"query":{
"match":{
"hobby":{
"query":"西红柿 面", #用空格分隔
"operator":"and" #表示and ,必须满足连个条件
}
}
},
"highlight":{
"fields":{
"hobby":{
}
}
}
}
##注意:and和or都是100%匹配率,因此我们可以自行设置匹配度
{
"query":{
"match":{
"hobby":{
"query":"西红柿 面", #用空格分隔
"minimum_should_match":"40%" #设置40%匹配度
}
}
},
"highlight":{
"fields":{
"hobby":{
}
}
}
}
#组合搜索
POST /name/type/_search
`必须有西红柿,不能包含盖饭,有汤匹配度更高`
{
"query":{
"bool":{
"must":{
"match":{
"hobby":"西红柿"
}
},
"must_not":{
"match":{
"hobby":"盖饭"
}
},
"should":[
{
"match":{
"hobby":"汤"
}
}
]
}
},
"highlight":{
"fields":{
"hobby":{
}
}
}
}
`必须包含西红柿和鸡蛋,如果是面就给10权重,饭就给2权重`
{
"query": {
"bool": {
"must": {
"match": {
"hobby": {
"query": "西红柿 鸡蛋",
"operator": "and"
}
}
},
"should": [
{
"match": {
"hobby": {
"query": "面",
"boost": 10 #设置权重
}
}
},
{
"match": {
"hobby": {
"query": "饭",
"boost": 2
}
}
}
]
}
},
"highlight": {
"fields": {
"hobby": {
}
}
}
}