我们在学习elasticsearch的核心概念之前,回顾下我们使用传统数据库查询数据的时候应该怎么做的?假设我们使用mysql数据库存储一些数据,我们的操作步骤是怎样的?
建立数据库->建表->插入数据->查询
elasticsearch的主要概念
- 索引(index)
一个索引可以理理解成一个关系型数据库
- 类型(type)
一种type就像一类表,比如user表,order表
注意:
- ES 5.x中一个index可以有多种type
- ES 6.x中一个index只能有一种type
- ES 7.x以后已经移除type这个概念
- 映射(mapping)
mapping定义了了每个字段的类型等信息。相当于关系型数据库中的表结构
- 文档(document)
一个document相当于关系型数据库中的一行记录
- 字段(field)
相当于关系型数据库表的字段
- 集群(cluster)
集群由一个或多个节点组成,一个集群有一个默认名称"elasticsearch"
- 节点(node)
集群的节点,一台机器或者一个进程
- 分片和副本(shard)
- 副本是分片的副本。分片有主分片(primary Shard)和副本分片(replica Shard)之分
- 一个Index数据在物理上被分布在多个主分片中,每个主分片只存放部分数据
- 每个主分片可以有多个副本,叫副本分片,是主分片的复制
索引的介绍和使用
- 新增
请求
curl -X PUT "localhost:9200/nba"
响应
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "nba"
}
- 获取
请求
curl -X GET "localhost:9200/nba"
响应
{
"nba": {
"aliases": {},
"mappings": {},
"settings": {
"index": {
"creation_date": "1563078001824",
"number_of_shards": "1",
"number_of_replicas": "1",
"uuid": "P-kmcRGlRECcBxAI_8mgaw",
"version": {
"created": "7020099"
},
"provided_name": "nba"
}
}
}
}
- 删除
请求
curl -X DELETE "localhost:9200/nba"
响应
{
"acknowledged": true
}
- 批量获取
请求
curl -x GET "localhost:9200/nba,cba"
响应
{
"cba": {
"aliases": {},
"mappings": {},
"settings": {
"index": {
"creation_date": "1563078437245",
"number_of_shards": "1",
"number_of_replicas": "1",
"uuid": "3rGtXSv_QTK-GU_xHKRvmw",
"version": {
"created": "7020099"
},
"provided_name": "cba"
}
}
},
"nba": {
"aliases": {},
"mappings": {},
"settings": {
"index": {
"creation_date": "1563078431931",
"number_of_shards": "1",
"number_of_replicas": "1",
"uuid": "bP6CZH5jSTGlhrTDzlq0bw",
"version": {
"created": "7020099"
},
"provided_name": "nba"
}
}
}
}
- 获取所有
请求(一)
curl -X GET "localhost:9200/_all"
响应(一)
{
"cba": {
"aliases": {},
"mappings": {},
"settings": {
"index": {
"creation_date": "1563078437245",
"number_of_shards": "1",
"number_of_replicas": "1",
"uuid": "3rGtXSv_QTK-GU_xHKRvmw",
"version": {
"created": "7020099"
},
"provided_name": "cba"
}
}
},
"nba": {
"aliases": {},
"mappings": {},
"settings": {
"index": {
"creation_date": "1563078431931",
"number_of_shards": "1",
"number_of_replicas": "1",
"uuid": "bP6CZH5jSTGlhrTDzlq0bw",
"version": {
"created": "7020099"
},
"provided_name": "nba"
}
}
}
}
请求(二)
curl -X GET "localhost:9200/_cat/indices?v"
响应(二)
- 存在(-I)
请求
curl -I "localhost:9200/nba"
响应
200 ok
- 关闭
请求
curl -X POST "localhost:9200/nba/_close"
响应
{
"acknowledged": true,
"shards_acknowledged": true
}
- 打开
请求
curl -X POST "localhost:9200/nba/_open"
响应
{
"acknowledged": true,
"shards_acknowledged": true
}
映射的介绍和使用
- 新增
请求
curl -X PUT "localhost:9200/nba/_mapping" -H 'Content-Type:application/json' -d'
{
"properties": {
"name": {
"type": "text"
},
"team_name": {
"type": "text"
},
"position": {
"type": "keyword"
},
"play_year": {
"type": "keyword"
},
"jerse_no": {
"type": "keyword"
}
}
}
'
响应
{
"acknowledged": true
}
- 获取
请求
curl -X GET "localhost:9200/vincent/_mapping"
响应
{
"nba": {
"mappings": {
"properties": {
"jerse_no": {
"type": "keyword"
},
"name": {
"type": "text"
},
"play_year": {
"type": "keyword"
},
"position": {
"type": "keyword"
},
"team_name": {
"type": "text"
}
}
}
}
}
- 批量获取
请求
curl -X GET "localhost:9200/nba,cba/mapping"
响应
{
"nba": {
"mappings": {
"properties": {
"jerse_no": {
"type": "keyword"
},
"name": {
"type": "text"
},
"play_year": {
"type": "keyword"
},
"position": {
"type": "keyword"
},
"team_name": {
"type": "text"
}
}
}
},
"cba": {
"mappings": {}
}
}
- 获取所有
请求(一)
curl -X GET "localhost:9200/_mapping"
响应(一)
{
"nba": {
"mappings": {
"properties": {
"jerse_no": {
"type": "keyword"
},
"name": {
"type": "text"
},
"play_year": {
"type": "keyword"
},
"position": {
"type": "keyword"
},
"team_name": {
"type": "text"
}
}
}
},
"cba": {
"mappings": {}
}
}
请求(二)
curl -X GET "localhost:9200/_all/_mapping"
响应(二)
{
"nba": {
"mappings": {
"properties": {
"jerse_no": {
"type": "keyword"
},
"name": {
"type": "text"
},
"play_year": {
"type": "keyword"
},
"position": {
"type": "keyword"
},
"team_name": {
"type": "text"
}
}
}
},
"cba": {
"mappings": {}
}
}
- 修改
请求
curl -X PUT "localhost:9200/nba/_mapping" -H 'Content-Type:application/json' -d'
{
"properties": {
"name": {
"type": "text"
},
"team_name": {
"type": "text"
},
"position": {
"type": "keyword"
},
"play_year": {
"type": "keyword"
},
"jerse_no": {
"type": "keyword"
},
"country": {
"type": "keyword"
}
}
}
'
响应
{
"acknowledged": true
}
文档的增删改查( 使用postman 操作)
- 新增文档
指定 id 新增
PUT localhost:9200/nba/_doc/1 (指定id)
{
"name":"哈登",
"team_name":"⽕火箭",
"position":"得分后卫",
"play_year":"10",
"jerse_no":"13"
}
响应
{
"_index": "nba",
"_type": "_doc",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
不指定id
POST localhost:9200/nba/_doc (不指定id)
{
"name": "库⾥里里",
"team_name": "勇⼠士",
"position": "组织后卫",
"play_year": "10",
"jerse_no": "30"
}
响应
{
"_index": "nba",
"_type": "_doc",
"_id": "cVi582sB6wrnBnZnFqog",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
- 自动创建索引
查看auto_create_index开关状态,请求 http://localhost:9200/_cluster/settings
当索引不存在并且auto_create_index为true的时候,新增文档时会自动创建索引
修改auto_create_index状态
PUT localhost:9200/_cluster/settings
{
"persistent": {
"action.auto_create_index": "false"
}
}
响应
{
"acknowledged": true,
"persistent": {
"action": {
"auto_create_index": "false"
}
},
"transient": {}
}
当auto_create_index=false时,指定一个不存在的索引,新增文档
PUT localhost:9200/wnba/_doc/1
{
"name": "杨超越",
"team_name": "梦之队",
"position": "组织后卫",
"play_year": "0",
"jerse_no": "18"
}
响应(报错)
{
"error": {
"root_cause": [
{
"type": "index_not_found_exception",
"reason": "no such index [wnba]",
"resource.type": "index_expression",
"resource.id": "wnba",
"index_uuid": "_na_",
"index": "wnba"
}
],
"type": "index_not_found_exception",
"reason": "no such index [wnba]",
"resource.type": "index_expression",
"resource.id": "wnba",
"index_uuid": "_na_",
"index": "wnba"
},
"status": 404
}
当auto_create_index=true时,指定一个不存在的索引,新增文档
{
"name": "杨超越",
"team_name": "梦之队",
"position": "组织后卫",
"play_year": "0",
"jerse_no": "18"
}
响应(正常)
{
"_index": "wnba",
"_type": "_doc",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
- 指定操作类型
PUT localhost:9200/nba/_doc/1?op_type=create
{
"name": "哈登",
"team_name": "火箭",
"position": "得分后卫",
"play_year": "10",
"jerse_no": "13"
}
响应
{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[1]: version conflict, document already exists (current version [2])",
"index_uuid": "oPdc9qAjRO-IlzPfymnpkg",
"shard": "0",
"index": "nba"
}
],
"type": "version_conflict_engine_exception",
"reason": "[1]: version conflict, document already exists (current version [2])",
"index_uuid": "oPdc9qAjRO-IlzPfymnpkg",
"shard": "0",
"index": "nba"
},
"status": 409
}
- 查看文档
GET localhost:9200/nba/_doc/1
{
"_index": "nba",
"_type": "_doc",
"_id": "1",
"_version": 3,
"_seq_no": 3,
"_primary_term": 1,
"found": true,
"_source": {
"name": "哈登",
"team_name": "火箭",
"position": "得分后卫",
"play_year": "10",
"jerse_no": "13"
}
}
- 查看多个文档
POST localhost:9200/_mget
{
"docs": [
{
"_index": "nba",
"_type": "_doc",
"_id": "1"
},
{
"_index": "nba",
"_type": "_doc",
"_id": "2"
}
]
}
响应
{
"docs": [
{
"_index": "nba",
"_type": "_doc",
"_id": "1",
"_version": 3,
"_seq_no": 3,
"_primary_term": 1,
"found": true,
"_source": {
"name": "哈登",
"team_name": "火箭",
"position": "得分后卫",
"play_year": "10",
"jerse_no": "13"
}
},
{
"_index": "nba",
"_type": "_doc",
"_id": "2",
"found": false
}
]
}
POST localhost:9200/nba/_mget
{
"docs": [
{
"_type": "_doc",
"_id": "1"
},
{
"_type": "_doc",
"_id": "2"
}
]
}
POST localhost:9200/nba/doc/mget
{
"docs": [
{
"_id": "1"
},
{
"_id": "2"
}
]
}
GET localhost:9200/nba/doc/mget
{
"ids" : ["1", "2"]
}
- 修改文档
根据提供的文档片段更新数据
POST localhost:9200/nba/_update/1
{
"doc": {
"name": "哈登",
"team_name": "火箭",
"position": "双能卫",
"play_year": "10",
"jerse_no": "13"
}
}
向_source字段,增加一个字段
POST localhost:9200/nba/_update/1
{
"script": "ctx._source.age = 18"
}
从_source字段,删除一个字段
POST localhost:9200/nba/_update/1
{
"script": "ctx._source.remove(\"age\")"
}
根据参数值,更新指定文档的字段
POST localhost:9200/nba/_update/1
{
"script": {
"source": "ctx._source.age += params.age",
"params": {
"age": 4
}
}
}
upsert 当指定的文档不存在时,upsert参数包含的内容将会被插入到索引中,作为一个新文档;如果指定的文档存在,ElasticSearch引擎将会执行指定的更新逻辑
POST localhost:9200/nba/_update/3
{
"script": {
"source": "ctx._source.allstar += params.allstar",
"params": {
"allstar": 4
}
},
"upsert": {
"allstar": 1
}
}
- 删除文档
DELETE localhost:9200/nba/_doc/1
搜索的简单使用
- 新建一个索引,并且指定mapping
PUT localhost:9200/nba
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"team_name": {
"type": "text"
},
"position": {
"type": "text"
},
"play_year": {
"type": "long"
},
"jerse_no": {
"type": "keyword"
}
}
}
}
- 新增document
PUT localhost:9200/nba/_doc/1
{
"name": "哈登",
"team_name": "火箭",
"position": "得分后卫",
"play_year": 10,
"jerse_no": "13"
}
PUT localhost:9200/nba/_doc/2
{
"name": "库里",
"team_name": "勇士",
"position": "控球后卫",
"play_year": 10,
"jerse_no": "30"
}
PUT localhost:9200/nba/_doc/3
{
"name": "詹姆斯",
"team_name": "湖人",
"position": "小前锋",
"play_year": 15,
"jerse_no": "23"
}
- term(词条)查询和full text(全文)查询
词条查询:词条查询不会分析查询条件,只有当词条和查询字符串完全匹配时,才匹配搜索
全文查询:ElasticSearch引擎会先分析查询字符串,将其拆分成多个分词,只要已分析的字段中包含词条的任意一个,或全部包含,就匹配查询条件,返回该文档;如果不包含任意一个分词,表示没有任何文档匹配查询条件
- 单条term查询
POST localhost:9200/nba/_search
{
"query": {
"term": {
"jerse_no": "23"
}
}
}
{
"took": 223,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.9808292,
"hits": [
{
"_index": "nba",
"_type": "_doc",
"_id": "3",
"_score": 0.9808292,
"_source": {
"name": "詹姆斯",
"team_name": "湖人",
"position": "小前锋",
"play_year": 15,
"jerse_no": "23"
}
}
]
}
}
- 多条term查询
POST localhost:9200/nba/_search
{
"query": {
"terms": {
"jerse_no": [
"23",
"13"
]
}
}
}
{
"took": 20,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "nba",
"_type": "_doc",
"_id": "1",
"_score": 1,
"_source": {
"name": "哈登",
"team_name": "火箭",
"position": "得分后卫",
"play_year": 10,
"jerse_no": "13"
}
},
{
"_index": "nba",
"_type": "_doc",
"_id": "3",
"_score": 1,
"_source": {
"name": "詹姆斯",
"team_name": "湖人",
"position": "小前锋",
"play_year": 15,
"jerse_no": "23"
}
}
]
}
}
- match_all
POST localhost:9200/nba/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 10
}
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "nba",
"_type": "_doc",
"_id": "1",
"_score": 1,
"_source": {
"name": "哈登",
"team_name": "火箭",
"position": "得分后卫",
"play_year": 10,
"jerse_no": "13"
}
},
{
"_index": "nba",
"_type": "_doc",
"_id": "2",
"_score": 1,
"_source": {
"name": "库里",
"team_name": "勇士",
"position": "控球后卫",
"play_year": 10,
"jerse_no": "30"
}
},
{
"_index": "nba",
"_type": "_doc",
"_id": "3",
"_score": 1,
"_source": {
"name": "詹姆斯",
"team_name": "湖人",
"position": "小前锋",
"play_year": 15,
"jerse_no": "23"
}
}
]
}
}
- match
POST localhost:9200/nba/_search
{
"query": {
"match": {
"position": "后卫"
}
}
}
{
"took": 17,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.94000727,
"hits": [
{
"_index": "nba",
"_type": "_doc",
"_id": "1",
"_score": 0.94000727,
"_source": {
"name": "哈登",
"team_name": "火箭",
"position": "得分后卫",
"play_year": 10,
"jerse_no": "13"
}
},
{
"_index": "nba",
"_type": "_doc",
"_id": "2",
"_score": 0.94000727,
"_source": {
"name": "库里",
"team_name": "勇士",
"position": "控球后卫",
"play_year": 10,
"jerse_no": "30"
}
}
]
}
}
- multi_match
POST localhost:9200/nba/_update/2
{
"doc": {
"name": "库里",
"team_name": "勇士",
"position": "控球后卫",
"play_year": 10,
"jerse_no": "30",
"title": "the best shooter"
}
}
POST localhost:9200/nba/_search
{
"query": {
"multi_match": {
"query": "shooter",
"fields": [
"title",
"name"
]
}
}
}
{
"query": {
"multi_match": {
"query": "shooter",
"fields": [
"*title",
"name"
]
}
}
}
- match_phrase
post localhost:9200/nba/_search
{
"query": {
"match_phrase": {
"position": "得分后卫"
}
}
}
{
"took": 8,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 3.3479528,
"hits": [
{
"_index": "nba",
"_type": "_doc",
"_id": "1",
"_score": 3.3479528,
"_source": {
"name": "哈登",
"team_name": "火箭",
"position": "得分后卫",
"play_year": 10,
"jerse_no": "13"
}
}
]
}
}
- match_phrase_prefix
POST localhost:9200/nba/_update/3
{
"doc": {
"name": "詹姆斯",
"team_name": "湖人",
"position": "小前锋",
"play_year": 15,
"jerse_no": "23",
"title": "the best small forward"
}
}
POST localhost:9200/nba/_search
{
"query": {
"match_phrase_prefix": {
"title": "the best s"
}
}
}
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1.8596163,
"hits": [
{
"_index": "nba",
"_type": "_doc",
"_id": "2",
"_score": 1.8596163,
"_source": {
"name": "库里",
"team_name": "勇士",
"position": "控球后卫",
"play_year": 10,
"jerse_no": "30",
"title": "the best shooter"
}
},
{
"_index": "nba",
"_type": "_doc",
"_id": "3",
"_score": 1.6542599,
"_source": {
"name": "詹姆斯",
"team_name": "湖人",
"position": "小前锋",
"play_year": 15,
"jerse_no": "23",
"title": "the best small forward"
}
}
]
}
}