elasticsearch 请求协议
http协议get请求
http://bigdata01:9200
curl请求协议格式
curl -XGET 'http://bigdata01:9200/path?query' -d 'body'
shell示例 获取文档(分片)数量: -> curl -H "Content-Type: application/json" -XGET 'http://localhost:9200/_count?pretty' -d '{ "query": { "match_all": {} }}'
shell示例 插入数据: -> curl -H "Content-Type: application/json" -XPUT 'http://bigdata03:9200/index/type/1' -d '{"first_name":"312","age":1,"interests":123}'
java 代码请求查询方式
public static void main(String[] args) throws Exception {
String url = "http://bigdata02:9200/_count?pretty";
JSONObject body = JSONObject.parseObject("{ \"query\": { \"match_all\": {} }}");
//发起post请求
String resp = post(url, null, body);//查询语句放在请求体中,请求头与请求体的ContentType都是application/json
System.out.println(resp);
}
运行结果显示文档分片数一个有十个
java 代码请求插入方式
public static void main(String[] args) throws Exception {
String url = "http://bigdata02:9200/megacorp/employee/1?pretty";//url后的路径表示: 索引/分类/id
//发起put请求
String resp = put(url, null, "{\"first_name\":\"a\",\"age\":1,\"interests\":[\"1\",\"2\"]}");
System.out.println(resp);
}
运行结果
修改分片数(主分片个数不能修改)
图1: curl -H "Content-Type: application/json" -XPUT 'http://bigdata03:9200/megacorp/_settings' -d '{"number_of_replicas": 1}'
图2: curl -H "Content-Type: application/json" -XPUT 'http://bigdata03:9200/megacorp/_settings' -d '{"number_of_replicas": 0}'
文档更新api(与覆盖的原理一样只是减少了部分网络开销)
POST /索引/文档类型/主键/_update
{
"doc" : {
"tags" : [ "testing" ],
"views": 0
}
}
批量获取数据,如果索引相同请求的示例如下
GET /website/_doc/_mget
{
"docs":[
{
"_id" : 2,
"_source":["title","text"] # 获取的字段列表,默认获取全部字段
},
{
"_id" : 1
}
]
}
如果索引通,可以将索引写入docs中,示例如下
GET /_mget
{
"docs" : [
{
"_index" : "myIndex1",
"_id" : 2
},
{
"_index" : "myIndex2",
"_id" : 1,
"_source": "views" #返回字段提取
}
]
}
批量操作,如果操作是不同的索引,示例如下
POST /_bulk
{ "index": { "_index": "index1", "_id": "555" }}
{ "title": "55555" }
{ "index": { "_index": "index2", "_id": "333" }}
{ "title": "44444" }
{ "index": { "_index": "index3", "_id": "444" }}
{ "title": "33333" }
如果操作的索引相同,可以将索引提出,不用重复指定
POST /website/_bulk
{ "index": { "_id": "555" }}
{ "title": "55555" }
{ "create": { "_id": "333" }}
{ "title": "44444" }
{ "index": { "_id": "444" }}
{ "title": "33333" }
创建索引并设置映射
PUT /小写索引名称
{
"settings" : {
"index" : {
"number_of_shards" : 3,
"number_of_replicas" : 2
}
},
"mappings": {
"_source": { "enabled": false }, <!--禁用_source数据字段,这一行需要删除,否则存不了数据-->
"date_detection": false, <!--关闭日期映射识别-->
"properties":{
"name1":{
"type":"text",
"analyzer": "standard"
},
"name2":{
"type": "object",
"properties": { <!--支持嵌套-->
"full": { "type": "text" },
"first": { "type": "text" },
"last": { "type": "text" }
}
},
"name3":{
"type":"object",
"dynamic": true <!-- true/false/strict - 动态添加/忽略新的字段/抛出异常 -->
}
}
}
}
修改映射
PUT 小写索引名称/_mapping
{
"properties":{
"name":{
"type":"keyword"
},
"age":{
"type":"long"
},
"sex":{
"type":"text"
}
}
}
组合查询使用bool用于组合各种查询语句 must,must_not,filter,should的上一层必须是bool,否则语法错误
如果没有 must
语句,那么至少需要能够匹配其中的一条 should
语句。但,如果存在至少一条 must
语句,则对 should
语句的匹配没有要求 ,即shoule在与must或者filter同级时,默认是不需要满足should中的任何条件的
根据这个规范,通常must与should不放在同一级目录下,通常将should放在must->bool下
POST /test1/_search
{
"query":{
"bool": { <!--组合语句,使用and组合条件-->
"must":[{"range": { "a" : { "gt" : 0 }}}], <!--and-->
"must_not": { "match": { "a": 10 }}, <!--not-->
"filter": { "match": { "b.b.a": 1 }}, <!--not,包含逻辑不参与评分-->
"should": [ { "match": { "b.b.c": 13 }}], <!--or must存在,minimum_should_match不存在,即当前不生效,可or逻辑,可以提升查询结果权重-->
"minimum_should_match": 1 <!--针对should至少需要满足的条件数量,允许使用百分比-->
}
}
}
逻辑语法 自适应判断,根据字段mapping选择匹配方式,如果是analyzed类型的文本,将会进行分词,其他类型均使用精确查询
{
"match": {
"a": 10
}
}
逻辑语法 区间判断
gt:大于 gte:大于等于 lt:小于 lte:小于等于
{
"range": {
"fieldName": {
"gt": "大于数值",
"lt": "小于数值"
}
}
}
逻辑语法,精确查询
{
"term": {
"字段名称": "字段值"
}
}
多个值精确存在匹配,它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件
{
"terms": {
"字段名称": ["search", "full_text", "nosql"] <!--或相关-->
}
}
验证查询是否合法,并检查搜索语句
POST /索引名称/_validate/query?explain
{
"query": {"match_all": {}}
}
根据字段排序
POST /test1/_search
{
"query": {
"bool": {
"must": {
"match":{
"b.b.b":2 <!--对象的属性通过.获取-->
}
}
}
},
"sort": { "a": { "order": "desc" }} <!--可以使用数组完成多级别排序-->
}
偏好搜索,可以使用用户会话id,用于保证相同的请求使用的分片相同
POST /test1/_search?preference=uuid
{
"query": {
"bool": {
"must": {
"match":{
"b.b.b":2
}
}
}
},
"sort": { "a": { "order": "asc" }}
}
游标查询 查询结果会返回一个scroll_id字段,值是base64编码的长字符串,值用于下一次查询使用,每查询一次,进行一次翻页
获取游标
POST /test1/_search?preference=uuid&scroll=1m
{
"query": {
"bool": {
"must": {
"match":{
"b.b.b":2
}
}
}
},
"sort": "_doc",
"size":5
}
使用游标 游标有失效是时间, scroll设置失效时间,每使用游标查询一次重置更新失效时间
POST /_search/scroll
{
"scroll": "1m",
"scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDnF1ZXJ5VGhlbkZldGNoAxZlc2o3ajR5NVNmZXRMS0hwb3BkUzJRAAAAAAAAE_MWR1k4UlVrNzNRVjZNSmpQQzRqdjdpQRZPdWZmOEVrVVN4T2QxVXRhandmbTBRAAAAAAAAEU0WX1R2MEQ0bGFUeDZ4OEV6ak9HSlNDURZWdlpucFJ6NVJzYWJxSEJfZE9iTDlRAAAAAAAAf7gWZVVEcHBQeEdRZHVmOFU5TUhSLThydw=="
}
查询结果获取选中的字段
POST /索引名称/_doc/_search
{
"_source": [ "显示的字段1", "显示的字段2" ]
}
数据类型
keyword 不分词,必须精确查询,允许分组聚合
text 分词允许全文检索,不允许分组聚合
全文text检索条件匹配方式
GET /索引名称/_search
{
"query": {
"match": {
"title": {
"query": "BROWN DOS!", <!--title是text类型,会被分析,查询默认使用或查询-->
"operator": "or" <!--默认为or,如果要求每一个词都存在,需要使用and-->
}
}
}
}
查询数据设置权重关键代码
{
"match": {
"字段名称": {
"query": "内容",
"boost": 2 <!--设置的查询权重评分-->
}
}
}
前缀匹配查询
GET /索引名称/_doc/_search
{
"query": {
"prefix": {
"字段名称": "字段值前缀"
}
}
}
聚合api
GET /cars/_doc/_search
{
"size" : 0,
"aggs" : {
"聚合之后的字段名称" : {
"terms" : {
"field" : "需要聚合的字段"
}
}
}
}
分组聚合语法,单次分组
POST /cars/_search
{
"size":0
, "aggs": {
"分组": {
"terms": {
"field": "分组字段"
},
"aggs": {
"总和": {
"sum": {
"field": "聚合字段"
}
}
}
}
}
}
多次分组
POST /cars/_search
{
"size": 0,
"aggs": {
"颜色分组": {
"terms": {
"field": "color"
},
"aggs": {
"名称分组": {
"terms": {
"field": "make"
},
"aggs": {
"总和": {
"sum": {
"field": "price"
}
}
}
}
}
}
}
}
根据区间范围分组,并聚合价格最大值,并查看每一组聚合中存在的make详情分布
{
"size": 0,
"aggs": {
"条形分组": {
"histogram": {
"field": "price",
"interval": 20000
},
"aggs": {
"最大值": {
"max": {
"field": "price"
}
},
"详情": {
"terms": {
"field": "make"
}
}
}
}
}
}
时间区间分区统计
{
"size": 0,
"aggs": {
"时序分组": {
"date_histogram": {
"field": "sold",
"interval": "month",
"format": "yyyy-MM-dd",
"min_doc_count": 0, <!--强制返回所有分组,及时分组为空也返回-->
"extended_bounds": { <!--设置分组区间的范围-->
"min": "2014-01-01",
"max": "2014-12-31"
}
},
"aggs": {
"价格总和": {
"sum": {
"field": "price"
}
},
"组合内部价格详情": {
"terms": {
"field": "price"
}
}
}
}
}
}
分组综合查询 按照月分组,统计每月价格总和,并统计每月下各种品牌销售价格总和
{
"size": 0,
"aggs": {
"时序分组": {
"date_histogram": {
"field": "sold",
"interval": "month",
"format": "yyyy-MM-dd",
"min_doc_count": 0,
"extended_bounds": {
"min": "2014-01-01",
"max": "2014-12-31"
}
},
"aggs": {
"价格总和": {
"sum": {
"field": "price"
}
},
"汽车品牌分组": {
"terms": {
"field": "make"
},
"aggs": {
"品牌计算销售总额": {
"sum": {
"field": "price"
}
}
}
}
}
}
}
}
使用全局数据嵌入分组内部
{
"size" : 0,
"query" : {
"match" : {
"make" : "ford"
}
},
"aggs" : { <!--使用query中的查询结果进行聚合-->
"ford类型的平均价格": {
"avg" : { "field" : "price" }
},
"all": {
"global" : {}, <!--声明全部数据的聚合-->
"aggs" : {
"总平均价格": {
"avg" : { "field" : "price" }
}
}
}
}
}
分组过滤 对聚合数据进行过滤,示例:选择ford类型并且时间大于2020-12-01的数据求价格平均值
POST /cars/_search
{
"size" : 0,
"query":{
"match": {
"make": "ford"
}
},
"aggs":{
"保留": {
"filter": {
"range": {
"sold": {
"gte": "2020-12-01"
}
}
},
"aggs": {
"average_price":{
"avg": {
"field": "price"
}
}
}
}
}
}
聚合排序
{
"aggs": {
"分组": {
"terms": {
"field": "make",
"order": [
{"颜色类型": "desc"},
{"总和": "asc"} <!--引用查询结果字段排序-->
]
},
"aggs": {
"总和": {
"sum": {
"field": "price"
}
},
"颜色类型": {
"cardinality": { <!--去重查询-->
"field": "color",
"precision_threshold" : 100 <!--去重误差权衡值 0–40000-->
}
},
"详情": {
"terms": {
"field": "price",
"order": { <!--详情排序-->
"_term": "desc"
}
}
}
}
}
}
}
聚合百分位显示统计
{
"size" : 0,
"aggs" : {
"百分位值" : {
"percentiles" : {
"field" : "latency" ,
"percents" : [50, 95.0, 99.0] <!--默认是1,2,5,25,50,95,99-->
}
},
"平均值" : {
"avg" : {
"field" : "latency"
}
}
}
}
百分数值用户占比
{
"size": 0,
"aggs": {
"区域": {
"terms": {
"field": "zone"
},
"aggs": {
"百分位值": {
"percentiles": {
"field": "latency"
}
},
"用户占比": {
"percentile_ranks": {
"field": "latency",
"values": [210, 800] <!--小于210的用户占比与小于800的用户占比-->
}
},
"平均值": {
"avg": {
"field": "latency"
}
}
}
}
}
}
创建索引模板,支持匹配索引并设定字段映射
POST /_template/temp
{
"template": "temp-*",
"order": 1,
"settings":{
"index":{
"number_of_shards":3,
"number_of_replicas":1,
"refresh_interval":"30s", <!--数据写入多久后可以被搜索到-->
"translog":{
"durability":"async", <!--translog的刷盘策略按sync_interval配置指定的时间周期进行-->
"sync_interval":"120s",
"flush_threshold_size":"1024mb" <!--超过这个大小会导致refresh操作,产生新的Lucene分段-->
}
}
},
"mappings": {
"date_detection": false,
"properties":{
"field1":{
"type":"text"
},
"field2":{
"type": "keyword"
}
}
}
}
对于近期不使用的索引可以关闭,关闭之后只会暂用磁盘空间
POST /索引名称/_flush 刷新
POST /索引名称/_close 关闭
POST /索引名称/_open 开启
路由数据到分片中,对相同的数据路由到相同的分片中,路由算法
shard = hash(routing) % 分片总数
在发起入库请求的时候可以手动指定routing,routing默认是文档的_id
POST /索引名称/文档类型?routing=baking
{
"字段1": "值1",
"字段2": "值2",
...
}
搜索可以传入routing去对应的分片中获取数据
POST /索引名称/文档类型/_search?routing=baking
{
}
设置别用,使用别名进行数据路由
# 设置别名
PUT /已存在的索引名称/_alias/别名
{
"routing": "别名",
"filter": {
"term": {
"路由字段": "别名"
}
}
}
#写入数据自动路由
POST /别名/_doc/
{
"路由字段": "别名",
"其他字段": "字段值"
}
直接使用elasicsearch中的sql插件查询
http://localhost:9200/_xpack/sql?format=json
POST /_xpack/sql?format=txt
{
"query": "SELECT count(*) FROM cars group by make,color limit 5"
}
将sql语句转化为DSL语句
POST _sql/translate
{
"query":"SELECT count(*),f2,sum(f5) FROM temp where data < '2002-03-01 00:00:00' and f4 < 500 and f5 < 5000 and f6 < 50 group by f2"
}