ES入门 -API
ES作为一个索引及搜索服务,对外提供丰富的REST接口,本次学习目的是对ES的API及流程有个初步的认识。
文章目录
1 创建索引库
ES的索引库是一个逻辑概念,它包括了分词列表及文档列表,同一个索引库中存储了相同类型的文档。它就相当于Abase中的表,或相当于Mongodb中的集合。
关于索引这个词:
- 索引(名词):ES是基于Lucene构建的一个搜索服务,从索引库搜索符合条件的索引数据
- 索引(动词):索引库刚建立的时候是空的,将数据添加到索引库的过程称之为索引。
介绍通过API创建索引库的方法,向ES客户端发送命令。
- 使用API建立索引库
PUT xc_course
{
"settings":{
"index":{
"number_of_shards":1,
"number_of_replicas":0
}
}
}
参数说明:
- number_of_shards:设置分片的数量,在集群中通常设置多个分片,表示一个索引库将拆分成多片分别存储不同的结点,提高了ES的处理能力和高可用性,入门程序使用单机环境,这里设置为1。
- number_of_replicas:设置副本的数量,设置副本是为了提高ES的高可靠性,单机环境设置为0.
以上创建的例子,创建xc_course索引库,共1个分片,0个副本:
返回JSON
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "xc_course"
}
查看已存在的索引
GET _cat/indices?v
返回JSON
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open xc_course MlDfdxD_SmeyX4JsJXl2Qg 1 0 0 0 208b 208b
green open test NjREh8RAQuWI4yKnwyc81w 1 0 0 0 208b 208b
green open kibana_sample_data_ecommerce HrH4jppYQHKYn0fs6Wi7YA 1 0 4675 0 4.7mb 4.7mb
yellow open ecommerce Hn1-Ri_FTzanbIAvZEi82A 1 1 4 0 33.7kb 33.7kb
green open kibana_sample_data_logs 9mED7BfFQVyDIKwSpdsRzQ 1 0 14074 0 9.9mb 9.9mb
green open .kibana_1 Fldo_dPxTNOZhkB83rm3Nw 1 0 182 15 154kb 154kb
green open kibana_sample_data_flights HLIxA43ERTe8VogPHhgZrg 1 0 13059 0 6mb 6mb
yellow open ecommerce1 6SWcHuTySHmkRXl_a-lN4w 1 1 0 0 21.8kb 21.8kb
2 创建映射
2.1 概念说明
在索引中每个文档都包括了一个或多个field,创建映射就是向索引库中创建field的过程,下边是ES与关系数据库的相关概念的类比
RDBMS | ES | 对比说明 |
---|---|---|
table | Index | 查询语句执行的对象,理论上table和xindex更加具有可比性,而不是type |
row | document | document结构更加松散灵活,row更严格 |
column | filed | ES尽可能的把字段与sql中的列作对应,并不是完全对应的上,如ES中字段可能是一个list |
schema | mapping | |
SQL | DSL |
注意:6.0之前的版本有type(类型)概念,type相当于关系数据库的表,ES官方将在ES9.0版本中彻底删除type。
上边讲的创建索引库相当于关系数据库中的数据库还是表?
- 1、如果相当于数据库就表示一个索引库可以创建很多不同类型的文档,这在ES中也是允许的。
- 2、如果相当于表就表示一个索引库只能存储相同类型的文档,ES官方建议 在一个索引库中只存储相同类型的文档。
2.2 创建映射
先来一个简单的映射
# 创建映射
POST xc_course/_mapping
{
"properties": {
"name": {
"type": "text"
},
"description": {
"type": "text"
},
"studymodel": {
"type": "keyword"
}
}
}
返回JSON
{
"acknowledged" : true
}
查看已创建的映射及字段类型
# 查看已创建的映射
GET xc_course/_mapping
返回JSON
{
"xc_course" : {
"mappings" : {
"properties" : {
"description" : {
"type" : "text"
},
"name" : {
"type" : "text"
},
"studymodel" : {
"type" : "keyword"
}
}
}
}
}
- 更新索引映射
# 更新索引映射 采用 别名 A->1 变成 1->B
# 1、 创建索引的别名
PUT i_base/_alias/1
# 2、 创建有新内容的索引及映射
PUT ii_base/_mapping
{
"properties": {
"name": {
"type": "text"
},
"description": {
"type": "text"
},
"studymodel": {
"type": "keyword"
},
"number":{
"type":"integer"
}
}
}
# 3 修改别名映射
POST _aliases
{
"actions":[
{
"remove":{"index":"i_base","alias":"1"}
},{
"add":{
"index":"ii_base","alias":"1"
}
}
]
}
2 常用映射类型
ES支持的数据类型:传送门>|–|<
1 text文本字段
- 1 analyzer:
通过analyzer属性指定分词器。
下边指定name的字段类型为text,使用ik分词器的ik_max_word分词模式。
"name": {
"type": "text",
"analyzer":"ik_max_word"
}
上边指定了analyzer是指在索引和搜索都使用ik_max_word,如果单独想定义搜索时使用的分词器则可以通过search_analyzer属性。
对于ik分词器建议是索引时使用ik_max_word将搜索内容进行细粒度分词,搜索时使用ik_smart提高搜索精确性
"name": {
"type": "text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_smart"
}
- 2 index
通过index属性指定是否索引。
默认为index=true,即要进行索引,只有进行索引才可以从索引库搜索到。
但是也有一些内容不需要索引,比如:商品图片地址只被用来展示图片,不进行搜索图片,此时可以将index设置
为false。
删除索引,重新创建映射,将pic的index设置为false,尝试根据pic去搜索,结果搜索不到数据
pic": {
"type": "text",
"index":false
}
- 3 store
是否在source之外存储,每个文档索引后会在 ES中保存一份原始文档,存放在"_source"中,一般情况下不需要设置store为true,因为在_source中已经有一份原始文档了。
2 keyword关键字字段:
上边介绍的text文本字段在映射时要设置分词器,keyword字段为关键字字段,通常搜索keyword是按照整体搜索,所以创建keyword字段的索引时是不进行分词的,比如:邮政编码、手机号码、身份证等。keyword字段通常用于过虑、排序、聚合等。
3 date日期类型
日期类型不用设置分词器。
通常日期类型的字段用于排序。
- format
通过format设置日期格式
例子:
下边的设置允许date字段存储年月日时分秒、年月日及毫秒三种格式。
{
"properties": {
"timestamp": {
"type": "date",
"format": "yyyy‐MM‐dd HH:mm:ss||yyyy‐MM‐dd"
}
}
}
数值类型
下边是ES支持的数值类型
- 尽量选择范围小的类型,提高搜索效率
- 对于浮点数尽量用比例因子,比如一个价格字段,单位为元,我们将比例因子设置为100这在ES中会按 分 存储,映射如下:
"price": {
"type": "scaled_float",
"scaling_factor": 100
}
由于比例因子为100,如果我们输入的价格是23.45则ES中会将23.45乘以100存储在ES中。
如果输入的价格是23.456,ES会将23.456乘以100再取一个接近原始值的数,得出2346。
使用比例因子的好处是整型比浮点型更易压缩,节省磁盘空间。
3 创建文档
API:
- 指定ID
PUT xc_course/_doc/1
{
"name":"ES学习",
"description":"ES学习,跟着API学习使用;这个是指定文档id为1;使用POST命令 让ES自动添加一个ID",
"studymodel":"多敲,多实践"
}
返回JSON
{
"_index" : "xc_course",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"result" : "updated",
"_shards" : {
"total" : 1,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}
- 使用POST 自动生成一个ID
# 创建文档 自增ID
POST xc_course/_doc/
{
"name":"不指定ID",
"description":"使用POST命令 让ES自动添加一个ID;",
"studymodel":"多敲,多实践"
}
返回JSON
{
"_index" : "xc_course",
"_type" : "_doc",
"_id" : "rgMaSnQB_HGnGvcnW-gm",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 1,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 5,
"_primary_term" : 1
}
- 查询指定的文档
# 查询创建的文档
GET xc_course/_doc/1
返回的JSON
{
"_index" : "xc_course",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 2,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "ES学习",
"description" : "ES学习,跟着API学习使用;这个是指定文档id为1,不指定的话 ES为自动添加一个ID;",
"studymodel" : "多敲,多实践"
}
}
- 查询所有创建的文档
GET xc_course/_search
返回JSON -略
- 查询某字段中包括x’x’x关键字的记录
# 查询name中包括 `指定` 关键字的的记录
GET xc_course/_search?q=name:指定
返回JSON
{
"took" : 5,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.90630186,
"hits" : [
{
"_index" : "xc_course",
"_type" : "_doc",
"_id" : "rQMYSnQB_HGnGvcnXujH",
"_score" : 0.90630186,
"_source" : {
"name" : "不指定ID",
"description" : "ES学不指定的话 ES为自动添加一个ID;",
"studymodel" : "多敲,多实践"
}
},
{
"_index" : "xc_course",
"_type" : "_doc",
"_id" : "rgMaSnQB_HGnGvcnW-gm",
"_score" : 0.90630186,
"_source" : {
"name" : "不指定ID",
"description" : "使用POST命令 让ES自动添加一个ID;",
"studymodel" : "多敲,多实践"
}
}
]
}
}
- 参数说明:
- took:本次操作花费的时间,单位为毫秒。
- timed_out:请求是否超时
- _shards:说明本次操作共搜索了哪些分片
- hits:搜索命中的记录
- hits.total : 符合条件的文档总数 hits.hits :匹配度较高的前N个文档
- hits.max_score:文档匹配得分,这里为最高分
- _score:每个文档都有一个匹配度得分,按照降序排列。
- _source:显示了文档的原始内容。
4 IK分词器
在添加文档时会进行分词,索引中存放的就是一个一个的词(term),当你去搜索时就是拿关键字去匹配词,最终找到词关联的文档。
4.1 测试分词器
GET _analyze
{
"text":"测试分词器,这是测试内容"}
返回JSON
{
"tokens" : [
{
"token" : "测",
"start_offset" : 0,
"end_offset" : 1,
"type" : "<IDEOGRAPHIC>",
"position" : 0
},
{
"token" : "试",
"start_offset" : 1,
"end_offset" : 2,
"type" : "<IDEOGRAPHIC>",
"position" : 1
},
{
"token" : "分",
"start_offset" : 2,
"end_offset" : 3,
"type" : "<IDEOGRAPHIC>",
"position" : 2
},
{
"token" : "词",
"start_offset" : 3,
"end_offset" : 4,
"type" : "<IDEOGRAPHIC>",
"position" : 3
},
{
"token" : "器",
"start_offset" : 4,
"end_offset" : 5,
"type" : "<IDEOGRAPHIC>",
"position" : 4
},
...
这是因为当前索引库使用的分词器对中文就是单字分词。
4.2 安装Ik分词器
GET _analyze
{"analyzer": "ik_max_word",
"text":"测试分词器,这是测试内容"}
返回json
{
"tokens" : [
{
"token" : "测试",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "分词器",
"start_offset" : 2,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "分词",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "器",
"start_offset" : 4,
"end_offset" : 5,
"type" : "CN_CHAR",
"position" : 3
},
{
"token" : "这是",
"start_offset" : 6,
"end_offset" : 8,
"type" : "CN_WORD",
"position" : 4
},
{
"token" : "测试",
"start_offset" : 8,
"end_offset" : 10,
"type" : "CN_WORD",
"position" : 5
},
{
"token" : "内容",
"start_offset" : 10,
"end_offset" : 12,
"type" : "CN_WORD",
"position" : 6
}
]
}
两种分词模式
ik分词器有两种分词模式:ik_max_word和ik_smart模式。
- ik_max_word:
会将文本做最细粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为“中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、大会堂、大会、会堂等词语。 - ik_smart:
会做最粗粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为中华人民共和国、人民大会堂。
# 分词类型划分
GET _analyze
{"analyzer": "ik_smart",
"text":"MCL测试分词器,粗粒度"}
GET _analyze
{"analyzer": "ik_max_word",
"text":"MCL分词器测试,细粒度"}
参考资料
https://www.jianshu.com/p/7d687c9dba4f
https://www.cnblogs.com/duanxz/p/5081178.html
https://blog.csdn.net/a275870703/article/details/80354734