当前位置:   article > 正文

ElasticSearch基础知识_es查看节点信息

es查看节点信息

数据类型

核心数据类型

  1. 字符串类型: text, keyword

  2. 数字类型:long, integer, short, byte, double, float, half_float, scaled_float

  3. 日期:date

  4. 日期 纳秒:date_nanos

  5. 布尔型:boolean

  6. 二进制:binary

  7. 范围类型: integer_range, float_range, long_range, double_range, date_range

复杂数据类型

数组类型:array
对象类型:object
嵌套类型:nested object(用于json对象数组)

地理位置数据类型

geo_point(点)、geo_shape(形状)

专用类型

  • ip类型:记录IP地址ip
  • 补全类型:实现自动补全completion
  • 记录分词数:token_count,用于统计字符串种的词条数量
  • 记录字符串hash值母乳murmur3

多字段特性multi-fields

允许对同一个字段采用不同的配置,比如分词,例如对人名实现拼音搜索,只需要在人名中新增一个子字段为pinyin即可

es节点信息及索引查询

# 查看所有节点
GET /_cat/nodes
# 查看es健康状况
GET /_cat/health
# 查看主节点
GET /_cat/master
# 查看所有索引
# 相当于mysql的show databases
GET /_cat/indices
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

类型type的操作(7版本之后已弃用)

文档操作

基础crud

// 根据id查询文档 索引/类型/id
// 这个只能根据id查,必须携带id
// 这个语句只能查真实的索引,不能查聚合的索引,
// 例如只能查索引index_2022.01.01,不能查index*
GET	localhost:9200/blog1/article/1

DELETE	localhost:9200/blog1/article/1

POST	localhost:9200/blog1/article/1
// article为表名,1为文档的id(就是es自带的id,不是我们的业务id),如果不指定,es会自动分配一个string类型的id
// 修改文档和创建文档的格式一样,id重复就是更新
{
	"id":1,
	"title":"亮剑野狼峪白刃战",
}


// 这也是更新,与不带_update更新不同的是
// 上面更新完之后再更新同样的内容_seq_no,_version会累加
// 这儿更新完之后再更新同样的内容_seq_no,_version不会累加,result返回noop(no operation)

// post和put一样
// 也可以增加属性,直接写就行,上面的也可以,post和put也都可以
POST /customer/external/1/_update
{
  "doc":{
    "name":"jay"
  }
}


// _bulk:批量写入数据

// 这的json不能换行,否则会报错
// 第一行是用来定义规则的
// index:创建或更新,create:创建,update:更新,delete:删除
// 上一条如果失败不会影响到下一条
POST /customer/external/_bulk
{"index":{"_id":"1"}}
{"author":"gaosilin","price":1000,"id":2,"birth":"2022-03-28T06:59:59Z"}
{"index":{"_id":"2"}}
{"author":"gaosiling","price":1000,"id":3}

// 下面执行的话,是需要合并到一起的
// 这里分开为了好看
// _retry_on_conflict:3 更新失败重试3次
POST /_bulk
{"delete":{"_index":"website","_type":"blog","_id":"123"}}

{"create":{"_index":"website","_type":"blog","_id":"123"}}
{"title":"my first blog first"}

{"index":{"_index":"website","_type":"blog"}}
{"title":"my first blog first"}

{"update":{"_index":"website","_type":"blog","_id":"123"}}
{"doc":{"title":"my first blog first"}}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

查询结果说明

// _version不是1,证明数据被更新过

// _seq_no和_primary_term做乐观锁操作
// 只要数据有改动它俩都会累加
// _seq_no 并发控制字段,每次更新就会+1,用来做乐观锁
// _primary_term 同上,主分片重新分配,如重启,就会变化

// found 数据被找到了

// 乐观锁
// 例如a,b并发都想修改1数据,a想把1改成2,b想把1改成3,
// 两者都只想改1,而不是改其改2或者3
// 这个时候就可以用_seq_no来控制,老版的是用_version控制
{
  "_index" : "customer",
  "_type" : "external",
  "_id" : "1",
  "_version" : 4,
  "_seq_no" : 3,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "john doe"
  }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

_seq_no和_primary_term实现乐观锁

// 两个只能有一个被改,如果想再改,需要if_seq_no+1
// if_seq_no if_primary_term 是文档级的还是类型及的还是索引级的暂时不关心,以后应用到再说

PUT /customer/external/1?if_seq_no=9&if_primary_term=2
{"name":"1"}

PUT /customer/external/1?if_seq_no=9&if_primary_term=2
{"name":"2"}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

es测试数据

POST /bank/account/_bulk

https://gitee.com/xlh_blog/common_content/blob/master/es%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE.json#

文档进阶操作

检索

// q=* 表示查询所有 默认只返回10条记录
GET bank/_search?q=*&sort=account_number:asc

// query dsl
// 我们以后都用这种方式
GET bank/_search
{
  "query":{
    "match_all": {}
  },
  "sort": [
    {
        "account_number": "asc"
    },
    {
      "balance": "desc"
    }
  ]
}



// 排序也可以这么写,上面的是简写
// 分页查询所有,并返回指定的字段
GET bank/_search
{
  "query":{
    "match_all": {}
  },
  "sort": [
    {
      "balance": {
        "order": "desc"
      }
    }
  ],
  "from": 0,
  "size": 20,
  "_source": ["balance","firstname"]
}




// 数值是精确匹配
GET bank/_search
{
  "query": {
    "match": {
      "balance": "49989"
    }
  }
}


//  这是模糊查询,也叫全文检索(按照评分score进行排序)
// Mill road 会将这个分词,最终Mill 和 road都会被查出来
// 如果查询不想被分词,则把match替换为match_phrase
GET bank/_search
{
  "query": {
    "match": {
      "address": "Mill road"
    }
  }
}


// 多字段匹配
// 也会进行匹配,mill和movico在address或者city里都可以被查出来
GET bank/_search
{
  "query": {
    "multi_match": {
      "query": "mill movico",
      "fields": ["address","city"]
    }
  }
}


// bool 复合查询,多条件查询
// should 字段最好属于值,不属于也可以,
// 主要的作用是会影响score,进而影响展示的先后顺序
// must must_not should 都会影响score
GET bank/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "gender": "M"
          }
        },
        {
          "match": {
            "address": "mill"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "age": "28"
          }
        }
      ],
      "should": [
        {
          "match": {
            "lastname": "Hines"
          }
        }
      ]
    }
  }
  
}







// filter对score没有影响
GET bank/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "age": {
              "gte": 18,
              "lte": 30
            }
          }
        },
        {
          "match": {
            "address": "mill road"
          }
        }
      ],
      "filter": {
        "range": {
          "age": {
            "gte": 10,
            "lte": 29
          }
        }
      }
    }
  }
}


// term 一般只针对具体的值进行查询,
// 我们规定,全文检索用 match,非text字段我们用term
// 第二个查询语句是不会返回任何值的,即使其中有一个数据的值就是 451 Humboldt Street
GET bank/_search
{
  "query": {
    "term": {
      "age": {
        "value": "28"
      }
    }
  }
}





GET bank/_search
{
  "query": {
    "term": {
      "address": {
        "value": "451 Humboldt Street"
      }
    }
  }
}




// match_phrase 与 字段.keyword 区别
// match_phrase 做词语匹配,只要值包含即可
// .keyword 做精确匹配,必须是这个值
GET bank/_search
{
  "query": {
    "match": {
      "address.keyword": "789 Madison"
    }
  }
}






GET bank/_search
{
  "query": {
    "match_phrase": {
      "address": "789 Madison"
    }
  }
}





// 使用query_string多字段查询
POST	localhost:9200/blog1/article/_search

{
	"query":{
			"query_string":{
				"fields":["title","content"],
				"query":"我是程序员"
			}
		},
	"size":50,
	"from":0
	
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235

查询条件的关键字

  1. match:模糊匹配,需要指定字段名,但是输入会进行分词,比如"hello world"会进行拆分为hello和world,然后匹配,如果字段中包含hello或者world,或者都包含的结果都会被查询出来,也就是说match是一个部分匹配的模糊查询。查询条件相对来说比较宽松。

  2. term: 这种查询和match在有些时候是等价的,比如我们查询单个的词hello,那么会和match查询结果一样,但是如果查询"hello world",结果就相差很大,因为这个输入不会进行分词,就是说查询的时候,是查询字段分词结果中是否有"hello world"的字样,而不是查询字段中包含"hello world"的字样,elasticsearch会对字段内容进行分词,“hello world"会被分成hello和world,不存在"hello world”,因此这里的查询结果会为空。这也是term查询和match的区别

  3. match_phase:会对输入做分词,但是需要结果中也包含所有的分词,而且顺序要求一样。以"hello world"为例,要求结果中必须包含hello和world,而且还要求他们是连着的,顺序也是固定的,hello that word不满足,world hello也不满足条件。

  4. query_string:和match类似,但是match需要指定字段名,query_string是在所有字段中搜索,范围更广泛。

  5. 其他

  • wildcard:通配符(一般不用,会影响效率),例如 苏*
  • prefix:前缀(一般不用,会影响效率)
  • fuzzy:模糊
  • range:范围(例如查6-10)
  • text:
  • missing:

聚合分析 aggregations

聚合提供了从数据中分组和提取数据的能力。最简单的聚合方法大致等于 SQL 的 GROUP BY 和聚合函数。

# 搜索address中包含mill的所有人的年龄分布以及平均年龄
# aggs,值被query出来后,进行聚合

# ageAgg 给聚合起个名字
# terms 聚合类型,看值有多少种可能
# size,如果age有100种可能,我们只取10个
# 返回的结果,key age的具体的值,doc_count 该值一共有多少条

# avg 求平均值

# size 0 表示不展示搜索的结果
GET bank/_search
{
  "query": {
    "match": {
      "address": "mill"
    }
  },
  "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 10
      }
    },
    "ageAvg": {
      "avg": {
        "field": "age"
      }
    },
    "balanceAvg":{
      "avg": {
        "field": "balance"
      }
    }
  },
  "size": 0
}







# 子聚合
# 按照年龄聚合,并且请求这些年龄段的这些人的平均薪资
GET bank/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "ageAgg":{
      "terms": {
        "field": "age",
        "size": 100
      },
      "aggs": {
        "balanceAvg": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}








# 查出所有年龄分布,并且这些年龄段种M的平均薪资和F的平均薪资以及这个年龄段的总体平均薪资


GET bank/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 100
      },
      
      "aggs": {
        "genderAgg": {
          "terms": {
            "field": "gender.keyword",
            "size": 100
          },
          "aggs": {
            "balanceAvg": {
              "avg": {
                "field": "balance"
              }
            }
          }
        },
        "balanceAvg":{
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114

映射

# 查询索引映射信息
GET bank/_mapping


# 创建索引并指定映射
PUT /my_index
{
  "mappings": {
    "properties": {
      "age":{
        "type": "integer"
      },
      "email":{
        "type": "keyword"
      },
      "name":{
        "type": "text"
      }
    }
  }
}



# 添加映射,只能添加新的字段,不能更新已有字段的映射
# index 是否可以用来检索
# store 是否存储
# analyzer 分词器
# doc_values 是否可以被聚合
PUT /my_index
{
  "mappings": {
    "properties": {
      "employee-id":{
        "type": "keyword",
        "index": true
      }
    }
  }
}





GET bank/_search
GET bank/_mapping
GET new_bank/_mapping
# 更新映射
# 对于已存在的字段,字段的类型是不能被更新的
# 我们需要创建一个新的索引进行数据迁移
PUT /new_bank
{
  "mappings": {
    "properties": {
      "account_number" : {
          "type" : "long"
        },
        "address" : {
          "type" : "text"
          
        },
        "age" : {
          "type" : "integer"
        },
        "balance" : {
          "type" : "long"
        },
        "city" : {
          "type" : "keyword"
        },
        "email" : {
          "type" : "keyword"
        },
        "employer" : {
          "type" : "keyword"
        },
        "firstname" : {
          "type" : "text"
        },
        "gender" : {
          "type" : "keyword"
        },
        "lastname" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "state" : {
          "type" : "keyword"
        }
    }
  }
}



# 数据迁移
# 可以不指定类型,数据是老版本的数据
# 在7以后的版本中就可以不指定type了
POST _reindex
{
  "source": {
    "index": "bank",
    "type": "account"
  },
  "dest": {
    "index": "new_bank"
  }
}
GET new_bank/_search
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115

nested

PUT my_index/_doc/1
{
  "group" : "fans",
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "user.first": "Alice"
          }
        },
        {
          "match": {
            "user.last": "Smith"
          }
        }
      ]
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

上面的查询两个条件都是必须,理论上来讲没有一个user是Smith Alice的,但实际情况我们是可以查出来的

这是因为es把first和last的所有值都分别存在了一个数组里,查询的时候es发现这两个值在其数组中都存在,就有了结果
在这里插入图片描述

// 指定user为nested类型就不会出现这种情况了
PUT my_index
{
  "mappings": {
    "properties": {
      "user": {
        "type": "nested" 
      }
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

特殊查询

查询每天7:50的数据

实际查的是15:50的数据,这里是因为es时区的关系

POST your_es_index*/_search
{
  "query": {
    "bool": {
      "filter": {
        "script": {
          "script": {
            "source": "doc['@timestamp'].value.getHour() == params.queryHour  && doc['@timestamp'].value.getMinute() == params.queryMinute ",
            "params": {
              "queryHour":7,
              "queryMinute": 50
            }
          }
        }  
      },
      "must": [
        {
          "term": {
            "license.keyword":"巴啦啦"
          }
        },
        {
          "range": {
            "@timestamp": {
              "gte": "2023-01-16T15:50:59.999+0800",
              "lte": "2024-01-17T15:50:00.000+0800"
            }
          }
        }
      ]
    }
  },
  "sort": [
    {
      "@timestamp": {
        "order": "desc"
      }
    }
  ],
"from": 0,
 "size": 366
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

部分知识引用自:
https://www.cnblogs.com/betterwgo/p/11571275.html
https://www.jianshu.com/p/7247ac3663f7

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/663313
推荐阅读
相关标签
  

闽ICP备14008679号