为什么用ES
简单说就是ES通过分词和倒排索引,专门处理关键字搜索场景,可以参考这篇文章:MySQL和Lucene索引对比分析 - 阿凡卢 - 博客园
入门推荐:Introduction 本书简介 · Elasticsearch Reference CN
进阶还是需要看官方文档:Query and filter context | Elasticsearch Guide [master] | Elastic
Go:GitHub - elastic/go-elasticsearch: The official Go client for Elasticsearch
ElasticSearch-PHP:快速开始 | Elasticsearch-PHP | Elastic
安装运行
下载:Download Elasticsearch | Elastic
安装:将解压后的文件夹移动到/usr/local/elasticsearch
启动:nohup ./elasticsearch -Ecluster.name=why_cluster -Enode.name=why_node
概念解析
Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices -> Types -> Documents -> Fields
- node:节点,一个es实例代表一个节点
- 分布式集群:es是分布式数据库,多个node组成一个集群
- index:一个node有多个index,可以理解为index为database
- type:table
- document:row
- field:column
日志文件
大部分日志文件都有log和json两种格式:
-rw-r--r-- 1 why staff 0 10 5 16:45 why_cluster_deprecation.log
-rw-r--r-- 1 why staff 0 10 5 16:45 why_cluster_audit.json
-rw-r--r-- 1 why staff 0 10 5 16:45 why_cluster_deprecation.json
-rw-r--r-- 1 why staff 0 10 5 16:45 why_cluster_index_indexing_slowlog.log
-rw-r--r-- 1 why staff 0 10 5 16:45 why_cluster_index_search_slowlog.log
-rw-r--r-- 1 why staff 0 10 5 16:45 why_cluster_index_search_slowlog.json
-rw-r--r-- 1 why staff 0 10 5 16:45 why_cluster_index_indexing_slowlog.json
-rw-r--r-- 1 why staff 35210 10 5 16:57 why_cluster_server.json
-rw-r--r-- 1 why staff 19243 10 5 16:57 why_cluster.log
-rw-r--r-- 1 why staff 285078 10 5 17:13 gc.log
启动日志文件:
- why_cluster.log
- why_cluster_server.log
慢查询日志文件:
- why_cluster_index_search_slowlog.log
- why_cluster_index_search_slowlog.json
慢查询索引文件:
- why_cluster_index_indexing_slowlog.log
- why_cluster_index_indexing_slowlog.json
查询日志文件:
- gc.log:
每有一次客户端查询,会看到一个java偏向锁相关的Cleanup记录
[2019-10-05T09:36:16.804+0000][57933][safepoint ] Application time: 2.0066631 seconds
[2019-10-05T09:36:16.804+0000][57933][safepoint ] Entering safepoint region: Cleanup
[2019-10-05T09:36:16.804+0000][57933][safepoint ] Leaving safepoint region
[2019-10-05T09:36:16.804+0000][57933][safepoint ] Total time for which application threads were stopped: 0.0002716 seconds, Stopping threads took: 0.0000905 seconds
RESTful API
前言:参数的pretty参数是为了格式化显示
创建index
curl -XPUT 'localhost:9200/why_index?pretty' -H 'Content-Type:application/json' -d '
{
"settings": {
"number_of_shards": 1, //分片
"number_of_replicas": 0 //副本
},
"analysis": {
"ik_max_word": {
"tokenizer": "ik_max_word" //分词器
}
},
"mappings": {
"properties": {
"code": {
"type": "keyword"
},
"name": {
"type": "text",
"analyzer": "ik_max_word"
},
"age": {
"type": "long"
},
"content": {
"type": "text",
"analyzer": "ik_max_word"
},
"is_del": {
"type": "boolean"
},
"create_time": {
"type": "date"
},
"section_id_list": {
"type": "long"
}
}
}
}
'
响应:
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "why_index"
}
查看index
curl -XGET 'localhost:9200/_cat/indices?v&pretty'
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open why_index wA5gizTmT7GuUmDzvEcYqg 5 1 0 0 1.1kb 1.1kb
设置index的mappings
ES 15 - Elasticsearch的数据类型 (text、keyword、date、object、geo等) - 瘦风 - 博客园
curl -XPOST 127.0.0.1:9200/why_index/why_type/_mapping?pretty -H 'Content-Type:application/json' -d '
{
"why_type": {
"properties": {
"code": {
"type": "keyword" //不需要分词,需要全匹配、排序的
},
"name": {
"type": "text", //需要分词
"analyzer": "ik_max_word" //指定分词器
},
"age": {
"type": "long"
},
"content": {
"type": "text",
"analyzer": "ik_max_word"
},
"is_del": {
"type": "boolean"
},
"create_time": {
"type": "date"
},
"relations":{
"properties":{
"section_id_list": {
"type": "long" //es默认使用整型数组存储整型
}
}
}
}
}
}
'
响应:
{
"acknowledged" : true
}
添加字段
添加新字段:
curl -XPOST 127.0.0.1:9200/why_index/why_type/_mapping?pretty -H 'Content-Type:application/json' -d '
{
"properties": {
"review_type": {
"type": "keyword"
},
"tagList": {
"type": "nested",
"properties": {
"key": {
"type": "keyword"
},
"level": {
"type": "long"
},
"showTag": {
"type": "text",
"analyzer": "ik_max_word"
},
"timestamp": {
"type": "long"
},
"type": {
"type": "keyword"
}
}
}
}
}
'
设置默认值
为review_type设置默认值,否则存量数据无法搜索到,people为映射,PEOPLE为设置值:
curl -XPOST 127.0.0.1:9200/why_index/why_type/_update_by_query?pretty -H 'Content-Type:application/json' -d '
{
"script": {
"long": "painless",
"inline": "ctx._source.review_type=params.people",
"params": {
"people": "PEOPLE"
}
}
}
'
查看index
curl -XGET http://127.0.0.1:9200/why_index?pretty
{
"why_index": {
"aliases": {},
"mappings": {
"why_type": {
"properties": {
"age": {
"type": "long"
},
"name": {
"type": "text"
}
}
}
},
"settings": {
"index": {
"creation_date": "1580291572161",
"number_of_shards": "1",
"number_of_replicas": "0",
"uuid": "dOqKdYV2T8OYHkOSaUQNEg",
"version": {
"created": "6080599"
},
"provided_name": "why_index"
}
}
}
}
查看index的settings
curl -XGET http://127.0.0.1:9200/why_index/_settings?pretty
{
"why_index" : {
"settings" : {
"index" : {
"creation_date" : "1580291572161",
"number_of_shards" : "1",
"number_of_replicas" : "0",
"uuid" : "dOqKdYV2T8OYHkOSaUQNEg",
"version" : {
"created" : "6080599"
},
"provided_name" : "why_index"
}
}
}
}
查看index的mappings
curl -XGET http://127.0.0.1:9200/why_index/_mappings?pretty
{
"why_index" : {
"mappings" : {
"doc" : {
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
}
删除index
curl -XDELETE http://127.0.0.1:9200/why_index?pretty
{
"acknowledged" : true
}
根据id添加或更新document
curl -XPUT 'localhost:9200/why_index/doc/1?pretty' -H 'Content-Type:application/json' -d '{"name":"why", "age":18}'
{
"_index" : "why_index",
"_type" : "doc",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
直接插入document
注意:生产环境一般都会根据mysql的主键id插入,直接插入会根据base64算法自动生成id,此时无法根据id查询
执行两次,由于2次自动生成不同的_id,所以会有两条name和age相同的记录:
-XPOST 'localhost:9200/why_index/doc?pretty' -H 'Content-Type:application/json' -d '{"name":"why", "age":18}'
-XPOST 'localhost:9200/why_index/doc?pretty' -H 'Content-Type:application/json' -d '{"name":"why", "age":18}'
根据id查询某个document
// 1为_id
curl -XGET 'localhost:9200/why_index/doc/1?pretty
通过url传参query查询
查询name包含why的记录,并按照_id降序排列:
curl -XGET 'localhost:9200/why_index/_search?q=name:why&sort=_id:desc&pretty'
通过DSL语句查询
这大概是最全的ElasticSearch能满足日常开发的DSL组合了_AirGo.的博客-CSDN博客_dsl filler
curl -XGET 'localhost:9200/why_index/_search?pretty' -H 'Content-Type:application/json' -d '
{
"query": {
"bool": {
"filter": {
"bool": {
"must": [
{
"terms": {
"relations.section_id_list": [
1
]
}
}
],
"should": [
{
"match": {
"name": {
"query": "WHY",
"operator": "OR"
}
}
}
]
}
},
"should": [
{
"multi_mach": {
"analyzer": "ik_max_word",
"fields": ["title", "content"],
"operator": "OR",
"query": "关键字"
}
},
{
"match": {
"name": "WHY"
}
}
],
"minimum_should_match": 1
}
},
"sort": [
{
"create_time": {
"order": "desc",
"unmapped_type": "long"
}
}
],
"from": 0,
"size": 10
}
'
根据id修改数据
curl -XPOST 'localhost:9200/why_index/doc/1/_update?pretty' -H 'Content-Type:application/json' -d '
{
"doc":{
"name":"weihaoyu"
}
}'
响应:
{
"_index" : "why_index",
"_type" : "doc",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}
根据id删除
删除id为3的记录:
curl -XDELETE 'localhost:9200/why_index/doc/3?pretty'
{
"_index" : "why_index",
"_type" : "doc",
"_id" : "3",
"_version" : 2,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 8,
"_primary_term" : 1
}
删除符合条件的document
curl -XPOST 'localhost:9200/why_index/_delete_by_query?pretty' -H 'Content-Type:application/json' -d '
{
"query":{
"match":{
"name":"why"
}
}
}'
响应:
{
"took" : 85,
"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" : [ ]
}
批量操作
更新id为3的数据、根据id=2更新插入数据、删除id=1的数据
curl -XPOST 'localhost:9200/why_index/doc/_bulk?pretty' -H 'Content-Type:application/json' -d '
{"update":{"_id":3}}
{"doc":{"name":"weihaoyu"}}
{"index":{"_id":2}}
{"name":"why","age":18}
{"delete":{"_id":1}}
'
响应:
{
"took" : 37,
"errors" : false,
"items" : [
{
"update" : {
"_index" : "why_index",
"_type" : "doc",
"_id" : "3",
"_version" : 3,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 7,
"_primary_term" : 1,
"status" : 200
}
},
{
"index" : {
"_index" : "why_index",
"_type" : "doc",
"_id" : "2",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 8,
"_primary_term" : 1,
"status" : 201
}
},
{
"delete" : {
"_index" : "why_index",
"_type" : "doc",
"_id" : "1",
"_version" : 2,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 9,
"_primary_term" : 1,
"status" : 200
}
}
]
}
删除index
curl -XDELETE 'localhost:9200/why_index/?pretty'
{
"acknowledged" : true
}
再查询返回404
curl -XGET 'localhost:9200/why_index/_search?pretty' -H 'Content-Type:application/json' -d '{"query":{"match_all":{}}, "sort":{"_id":"asc"} }'
{
"error" : {
"root_cause" : [
{
"type" : "index_not_found_exception",
"reason" : "no such index [why_index]",
"resource.type" : "index_or_alias",
"resource.id" : "why_index",
"index_uuid" : "_na_",
"index" : "why_index"
}
],
"type" : "index_not_found_exception",
"reason" : "no such index [why_index]",
"resource.type" : "index_or_alias",
"resource.id" : "why_index",
"index_uuid" : "_na_",
"index" : "why_index"
},
"status" : 404
}