ElasticSearch操作
一、ES快速入门
1). 创建索引库
逻辑概念,包括了分词列表以及文档列表,,同一个索引库中存储了相同类型的文档,相当于表中的一条记录,索引库相当于一张表
- 索引:将数据添加到索引库的过程或者从索引库搜索符合条件索引数据。
- 官方建议一个索引库只存储相同类型的文档
put/post请求:
http://localhost:9200/索引库名称
{
"settings":{
"index":{
"number_of_shards":1, # 分片数量,存储到不同的节点,提高处理能力和高可用性
"number_of_replicas":0 # 每个节点的副本数量,提高 高可用性
}
}
}
2). 创建映射
ES9.0中彻底删除type的概念,这里使用doc代表type,弱化type
每个文档都包含一个或者多个field
创建映射就是创建field域
-
ES中与关系型数据的类比
-
document
:row
-
Field
:Columns
-
映射能够添加,但是不能直接修改或者删除,如果需要修改或者删除,需要将整个索引库删除之后重建!
post请求:
http://localhost:9200/索引库名称/类型名称doc/_mapping
{
"properties": {
"name": {
"type": "text", # 字符串映射(域)
"analyzer: "ik_max_ward", # 创建索引时指定最细粒度分词
"search_analyzer" : "ik_smart", # 指定该域搜索时的分词方式,以提高搜索精确性
"index": true, # 为其创建索引,该映射可被搜索,反之亦然
"store": false # 使用在_source之外存储,_source已经有啦一份,一般不需要设置为true
},
"phoneNumber": {
"type": "keyword" # keyword, 关键字段,整体索引,不分词;比如省份证,手机号等
# 通常用于过滤. 排序. 聚合等
},
"timestamp": {
"type": "date", # 日期类型,不用设置分词,通常用于查询结果排序
"format": "yyyy-MM-dd HH:mm:ss || yyyy-MM-dd" # 设置了两种日期模式
},
"price": {
"type": "scaled_float", # 数值类型,尽量选择小范围的类型,提高查询效率
"scaling_factor": 100 # 比例因子,比如 ¥99.98 ,内部会存为9988分,但是查询结果还是99.98,如果小数位超过比例因子,会被四舍五入
}
}
}
3). 创建文档
- 文档相当于MySQL中表的记录
- 请求为get/post
- 如果不指定id会自动生成id
put/post请求:
http://localhost:9200/索引库名称/doc/id值
{
"name": "hahadasheng",
"phoneNumber": "18888999988",
"timestamp": "2018-10-10 12:12:12",
"price": 998.99
}
4). 查询文档
- 全部查询get请求:
http://localhost:9200/xc_course/doc/_search
- 关键字查询get请求:
http://localhost:9200/xc_course/doc/_search?q=name:java&q=type:niubi
- 根据id查询get请求:
http://localhost:9200/xc_course/doc/id值
- 查询结果附加字段解析
字段 | 说明 |
---|---|
took | 本次操作花费的时间,单位为毫秒。 |
timed_out | 请求是否超时 |
_shards | 说明本次操作共搜索了哪些分片 |
hits | 搜索命中的记录 |
hits.total | 符合条件的文档总数 |
hits.hits | 匹配度较高的前N个文档 |
hits.max_score | 文档匹配得分,这里为最高分 |
_score | 每个文档都有一个匹配度得分,按照降序排列。 |
_source | 显示了文档的原始内容。 |
5). 索引管理
ES提供不同的客户端
-
TransportClient
: 8.0 之后计划删除, Java Low Level REST Client
-
Java High Level REST Client
: 官方推荐,但是目前功能不完善,需要使用Low Level配合使用
二、映射
在索引和搜索时去使用ik分词器,指定其它类型的field,比如日期类型、数值类型等。
1). 映射维护的方法
- 查询所有索引的映射,get请求。
http://localhost:9200/_mapping
- 创建映射,post请求
http://localhost:9200/xc_course/doc/_mapping
{
"properties": {
"name": {
"type": "text"
},
"description": {
"type": "text"
},
"studymodel": {
"type": "keyword"
}
}
}
- 映射创建成功可以添加新字段,已有字段不允许更新
重复提交新的映射请求即可。
- 删除映射,只有通过删除索引库才能删除映射!
2). 常用的映射类型
- ES6.2核心的字段类型如下
2). text类型的字符串
字符串包括text和keyword两种类型
- 通过analyzer属性指定分词器
# 指定name的字段类型为text,使用ik分词器的ik_max_word分词模式
"name": {
"type": "text",
"analyzer":"ik_max_word"
}
# 上边指定了analyzer是指在索引和搜索都使用ik_max_word,
# 如果单独想定义搜索时使用的分词器则可以通过search_analyzer属性
"name": {
"type": "text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_smart"
}
- 通过index属性指定是否索引
- 默认为index=true,即要进行索引,只有进行索引才可以从索引库搜索到
- 有一些内容不需要索引,比如:商品图片地址只被用来展示图片,不进行搜索图片,此时可以将index设置为false。
"pic": {
"type": "text",
"index":false
}
store:是否在source之外存储,每个文档索引后会在 ES中保存一份原始文档,存放在"_source"中,一般情况下不需要设置store为true,因为在_source中已经有一份原始文档了。
测试案例
# 删除xc_course/doc下的映射
# 创建新映射: Post http://localhost:9200/xc_course/doc/_mapping
{
"properties": {
"name": {
"type": "text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_smart"
},
"description": {
"type": "text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_smart"
},
"pic":{
"type":"text",
"index":false
},
"studymodel":{
"type":"text"
}
}
}
# 插入文档:http://localhost:9200/xc_course/doc/4028e58161bcf7f40161bcf8b77c0000
{
"name":"Java Python Golang 你选谁?",
"description":"都很牛逼,关键看自己的方向,大数据Web选Java, AI人工智能选Python,区块链等选Golang",
"pic":"group1/M00/00/01/wKhlQFqO4MmAOP53AAAcwDwm6SU490.jpg",
"studymodel":"201002"
}
# 测试查询
Get http://localhost:9200/xc_course/_search?q=name:开发
Get http://localhost:9200/xc_course/_search?q=description:开发
Get http://localhost:9200/xc_course/_search?q=pic:group1/M00/00/01/wKhlQFqO4MmAOP53AAAcwDwm6SU490.jpg
Get http://localhost:9200/xc_course/_search?q=studymodel:201002
# 通过测试发现: name和description都支持全文检索,pic不可作为查询条件。
3). keyword关键字字段
通常搜索keyword是按照整体搜索,所以创建keyword字段的索引时是不进行分词的,比如:邮政编码、手机号码、身份证等。keyword字段通常用于过虑、排序、聚合等。
- 测试
# 创建/添加映射: Post http://localhost:9200/xc_course/doc/_mapping
{
"properties": {
"studymodel":{
"type":"keyword"
},
"name":{
"type":"keyword"
}
}
}
# 插入文档
{
"name": "java编程基础",
"description": "java语言是世界第一编程语言,在软件开发领域使用人数最多。",
"pic":"group1/M00/00/01/wKhlQFqO4MmAOP53AAAcwDwm6SU490.jpg",
"studymodel": "201001"
}
# 根据studymodel查询文档
get http://localhost:9200/xc_course/_search?q=name:java
# name 是keyword类型,所以查询方式是精确查询
4). date日期类型
- 日期类型不用设置分词器。
- 通常日期类型的字段用于排序。
- 通过
format
设置日期格式
# 创建/添加映射: Post http://localhost:9200/xc_course/doc/_mapping
# 设置允许date字段存储年月日时分秒、年月日及毫秒三种格式。
{
"properties": {
"timestamp": {
"type": "date",
"format": "yyyy‐MM‐dd HH:mm:ss||yyyy‐MM‐dd"
}
}
}
# 插入文档
{
"name": "spring开发基础",
"description": "spring 在java领域非常流行,java程序员都在用。",
"studymodel": "201001",
"pic":"group1/M00/00/01/wKhlQFqO4MmAOP53AAAcwDwm6SU490.jpg",
"timestamp":"2018‐07‐04 18:28:58"
}
5). 数值类型
- ES支持的数值类型
- 尽量选择范围小的类型,提高搜索效率
- 对于浮点数尽量用比例因子,比如一个价格字段,单位为元,我们将比例因子设置为100这在ES中会按 分 存储,映射如下:
# 更新的field字段
"price": {
"type": "scaled_float",
"scaling_factor": 100
},
由于比例因子为100,如果我们输入的价格是23.45则ES中会将23.45乘以100存储在ES中。如果输入的价格是23.456,ES会将23.456乘以100再取一个接近原始值的数,得出2346。使用比例因子的好处是整型比浮点型更易压缩,节省磁盘空间。如果比例因子不适合,则从下表选择范围小的去用:
- 案例
# 插入文档,自定义id http://localhost:9200/xc_course/doc/3
{
"name": "spring开发基础",
"description": "spring 在java领域非常流行,java程序员都在用。",
"studymodel": "201001",
"pic":"group1/M00/00/01/wKhlQFqO4MmAOP53AAAcwDwm6SU490.jpg",
"timestamp":"2018‐07‐04 18:28:58",
"price":38.6
}
6). 综合案例
- 创建映射post
http://localhost:9200/xc_course/doc/_mapping
{
"properties": {
"description": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"name": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"pic":{
"type":"text",
"index":false
},
"price": {
"type": "float"
},
"studymodel": {
"type": "keyword"
},
"timestamp": {
"type": "date",
"format": "yyyy‐MM‐dd HH:mm:ss||yyyy‐MM‐dd||epoch_millis"
}
}
}
- 插入文档POST
http://localhost:9200/xc_course/doc/1
{
"name": "Java",
"description": "Java牛逼",
"studymodel": "201002",
"price":38.6,
"timestamp":"2018-04-25 19:11:35",
"pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg"
}