一、基本概念
cluster | 整个elasticsearch 默认就是集群状态,整个集群是一份完整、互备的数据。 |
node | 集群中的一个节点,一般只一个进程就是一个node |
shard | 分片,即使是一个节点中的数据也会通过hash算法,分成多个片存放,默认是5片。 |
index | 相当于rdbms的database, 对于用户来说是一个逻辑数据库,虽然物理上会被分多个shard存放,也可能存放在多个node中。 |
type | 类似于rdbms的table,但是与其说像table,其实更像面向对象中的class , 同一Json的格式的数据集合。 |
document | 类似于rdbms的 row、面向对象里的object |
field | 相当于字段、属性 |
二、基本操作
1.利用kibana学习 elasticsearch restful api (DSL)
public class Movie {
String id;
String name;
Double doubanScore;
List<Actor> actorList;
}
public class Actor{
String id;
String name;
}
这两个对象如果放在关系型数据库保存,会被拆成2张表,但是elasticsearch是用一个json来表示一个document。
所以他保存到es中应该是:
{
“id”:”1”,
“name”:”operation red sea”,
“doubanScore”:”8.5”,
“actorList”:[
{“id”:”1”,”name”:”zhangyi”},
{“id”:”2”,”name”:”haiqing”},
{“id”:”3”,”name”:”zhanghanyu”}
]
}
2.对数据的操作
1)GET /_cat/indices?v #v的意思为横向显示,会将json转换成横向表的形式显示,方便查看
es 中会默认存在一个名为.kibana的索引
表头的含义
health | green(集群完整) yellow(单点正常、集群不完整) red(单点不正常) |
status | 是否能使用 |
index | 索引名 |
uuid | 索引统一编号 |
pri | 主节点几个 |
rep | 从节点几个 |
docs.count | 文档数 |
docs.deleted | 文档被删了多少 |
store.size | 整体占空间大小 |
pri.store.size | 主节点占 |
2) PUT /movie_index
增加一个索引
3)DELETE /movie_index
删除一个索引,但ElasticSearch的删除并不是真正的清除数据,而是基于版本号机制(类似于github),进行软删除。
4)新增一个document
PUT /movie_index/movie/1
{ "id":1,
"name":"operation red sea",
"doubanScore":8.5,
"actorList":[
{"id":1,"name":"zhang yi"},
{"id":2,"name":"hai qing"},
{"id":3,"name":"zhang han yu"}
]
}
PUT /movie_index/movie/2
{
"id":2,
"name":"operation meigong river",
"doubanScore":8.0,
"actorList":[
{"id":3,"name":"zhang han yu"}
]
}
PUT /movie_index/movie/3
{
"id":3,
"name":"incident red sea",
"doubanScore":5.0,
"actorList":[
{"id":4,"name":"zhang chen"}
]
}
如果之前没建过index或者type,es 会自动创建。
5)GET movie_index/movie/1
直接通过id查找记录
6)修改---整体替换
PUT /movie_index/movie/3
{
"id":"3",
"name":"incident red sea",
"doubanScore":"5.0",
"actorList":[
{"id":"1","name":"zhang chen"}
]
}
和新增没什么区别,不是在原来的基础上进行修改,而是覆盖数据。
7)修改某一个字段
POST movie_index/movie/3/_update
{
"doc": {
"doubanScore":7.0
}
}
8)删除一个document
DELETE movie_index/movie/3
9)搜索type全部数据
GET movie_index/movie/_search
得到的结果
{
"took": 2, //耗费时间 毫秒
"timed_out": false, //是否超时
"_shards": {
"total": 5, //发送给全部5个分片
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 3, //命中3条数据
"max_score": 1, //最大评分
"hits": [ // 结果
{
"_index": "movie_index",
"_type": "movie",
"_id": 2,
"_score": 1,
"_source": {
"id": "2",
"name": "operation meigong river",
"doubanScore": 8.0,
"actorList": [
{
"id": "1",
"name": "zhang han yu"
}
]
}
。。。。。。。。
。。。。。。。。
}
10)按条件查询(全部)
GET movie_index/movie/_search
{
"query":{
"match_all": {}
}
}
11)按分词查询
GET movie_index/movie/_search
{
"query":{
"match": {"name":"red"}
}
}
注意结果的评分
12)按分词子属性查询
GET movie_index/movie/_search
{
"query":{
"match": {"actorList.name":"zhang"}
}
}
13)按短语查询,不再利用分词技术,直接用短语在原始数据中匹配
GET movie_index/movie/_search
{
"query":{
"match_phrase": {"name":"operation red"}
}
}
14)fuzzy查询
GET movie_index/movie/_search
{
"query":{
"fuzzy": {"name":"rad"}
}
}
校正匹配分词,当一个单词都无法准确匹配,es通过一种算法对非常接近的单词也给与一定的评分,能够查询出来,但是消耗更多的性能。
15)过滤--查询前过滤(推荐)
gt | 大于 |
lt | 小于 |
gte | 大于等于 |
lte | 小于等于 |
GET movie_index/movie/_search
{
"query": {
"bool": {
"filter": {
"range": {
"doubanScore": {"gte": 8}
}
}
}
}
}
16)排序
GET movie_index/movie/_search
{
"query":{
"match": {"name":"red sea"}
}
, "sort": [
{
"doubanScore": {
"order": "desc"
}
}
]
}
17)分页查询
GET movie_index/movie/_search
{
"query": { "match_all": {} },
"from": 1,
"size": 1
}
这里类似于mysql的分页
18)指定查询的字段
GET movie_index/movie/_search
{
"query": { "match_all": {} },
"_source": ["name", "doubanScore"]
}
19)高亮
GET movie_index/movie/_search
{
"query":{
"match": {"name":"red sea"}
},
"highlight": {
"fields": {"name":{} }
}
}
自定义标签
GET movie_index/movie/_search
{
"query":{
"match": {"name":"red sea"}
},
"highlight": {
"pre_tags": ["<b>"],
"post_tags": ["</b>"],
"fields": {"name":{} }
}
}
20)聚合
取出每个演员共参演了多少部电影
GET movie_index/movie/_search
{
"aggs": {
"groupby_actor": {
"terms": {
"field": "actorList.name.keyword"
}
}
}
}
每个演员参演电影的平均分是多少,并按评分排序
GET movie_index/movie/_search
{
"aggs": {
"groupby_actor_id": {
"terms": {
"field": "actorList.name.keyword" ,
"order": {
"avg_score": "desc"
}
},
"aggs": {
"avg_score":{
"avg": {
"field": "doubanScore"
}
}
}
}
}
}
三、关于mapping
之前说type可以理解为table,那每个字段的数据类型是如何定义的呢
查看看mapping
GET movie_index/_mapping/movie |
实际上每个type中的字段是什么数据类型,由mapping定义。
但是如果没有设定mapping系统会自动,根据一条数据的格式来推断出应该的数据格式。
- true/false → boolean
- 1020 → long
- 20.1 → double
- “2018-02-01” → date
- “hello world” → text +keyword
默认只有text会进行分词,keyword是不会分词的字符串。
mapping除了自动定义,还可以手动定义,但是只能对新加的、没有数据的字段进行定义。一旦有了数据就无法再做修改了。
注意:虽然每个Field的数据放在不同的type下,但是同一个名字的Field在一个index下只能有一种mapping定义。
四、中文分词