【ElasticSearch】 ElasticSearch基本概念和RESTful API(四)

ElasticSearch基本概念

索引

  索引(index)是Elasticsearch对逻辑数据的逻辑存储,所以它可以分为更小的部分。 可以把索引看成关系型数据库的表,索引的结构是为快速有效的全文索引准备的,特别是它不存储原始值。 Elasticsearch可以把索引存放在一台机器或者分散在多台服务器上,每个索引有一或多个分片(shard),每个 分片可以有多个副本(replica)。

文档

  • 存储在Elasticsearch中的主要实体叫文档(document)。用关系型数据库来类比的话,一个文档相当于数据库 表中的一行记录。
  • Elasticsearch和MongoDB中的文档类似,都可以有不同的结构,但Elasticsearch的文档中,相同字段必须有相 同类型。
  • 文档由多个字段组成,每个字段可能多次出现在一个文档里,这样的字段叫多值字段(multivalued)。
  • 每个字段的类型,可以是文本、数值、日期等。字段类型也可以是复杂类型,一个字段包含其他子文档或者数 组。

映射

  所有文档写进索引之前都会先进行分析,如何将输入的文本分割为词条、哪些词条又会被过滤,这种行为叫做 映射(mapping)。一般由用户自己定义规则。

文档类型

  • 在Elasticsearch中,一个索引对象可以存储很多不同用途的对象。例如,一个博客应用程序可以保存文章和评论。
  • 每个文档可以有不同的结构。
  • 不同的文档类型不能为相同的属性设置不同的类型。例如,在同一索引中的所有文档类型中,一个叫title的字段 必须具有相同的类型。

RESTful API

  在Elasticsearch中,提供了功能丰富的RESTful API的操作,包括基本的CRUD、创建索引、删除索引等操作。

  本例演示示例Elasticsearch安装,参考:【ElasticSearch】 ElasticSearch安装(一)

  Elasticsearch-Head插件安装,参考:【ElasticSearch】 elasticsearch-head插件安装(二)

  本例通过Elasticsearch-Head插件访问Elasticsearch RESTful API

创建非结构化索引

1、创建索引

 1 # 创建索引
 2 PUT /test 
 3 {
 4     "settings": {
 5           "index": {
 6             "number_of_shards": "2", #分片数
 7             "number_of_replicas": "0" #副本数 
 8         }
 9     } 
10 }
11 
12 #删除索引 
13 DELETE /test 
14 {
15     "acknowledged": true
16 }

  效果如下:

  

2、插入数据

  URL规则:  POST /{索引}/{类型}/{id}

 1 POST /test/doc/1001
 2 #数据 
 3 {
 4     "id":1001, 
 5     "name":"张三", 
 6     "age":20, 
 7     "sex":""
 8 }
 9 
10 #=======================
11 #响应 
12 {
13     "_index": "test",
14     "_type": "doc",
15     "_id": "1001",
16     "_version": 1,
17     "result": "created",
18     "_shards": {
19         "total": 1,
20         "successful": 1,
21         "failed": 0
22     },
23     "_seq_no": 0,
24     "_primary_term": 1
25 }

  效果如下:

  

  说明:非结构化的索引,不需要事先创建,直接插入数据默认创建索引。

1 POST /test/doc/
2 # 不指定id插入数据:
3 {
4     "id":1001, 
5     "name":"张三", 
6     "age":20, 
7     "sex":""
8 }

  

3、更新数据

  在Elasticsearch中,文档数据是不为修改的,但是可以通过覆盖的方式进行更新。

1 PUT /test/doc/1001
2 {
3     "id":1001, 
4     "name":"张三", 
5     "age":21, 
6     "sex":""
7 }

  效果如下:

  

  数据被覆盖

  

  问题来了,可以局部更新吗? -- 可以的。 前面不是说,文档数据不能更新吗? 其实是这样的: 在内部,依然会查询到这个文档数据,然后进行覆盖操作,步骤如下:

  1. 从旧文档中检索JSON
  2. 修改它
  3. 删除旧文档
  4. 索引新文档

  局部更新示例

1 POST /test/doc/1001/_update
2 #注意:这里多了_update标识
3 { 
4     "doc": {
5         "age":23 
6     }
7 }

  局部更新效果

  

4、删除数据

  在Elasticsearch中,删除文档数据,只需要发起DELETE请求即可。

1 DELETE /test/doc/1001

  效果如下:

  

  需要注意的是,result表示已经删除,version也更加了。

  如果删除一条不存在的数据,会响应404:

  

5、搜索数据

  1)根据id搜索数据

 1 GET /test/doc/1tKgnnIBpJjTHm8lQ7Jx
 2 
 3 #响应 
 4 {
 5     "_index": "test",
 6     "_type": "doc",
 7     "_id": "1tKgnnIBpJjTHm8lQ7Jx",
 8     "_version": 1,
 9     "_seq_no": 1,
10     "_primary_term": 1,
11     "found": true,
12     "_source": {
13         "id": 1001,
14         "name": "张三",
15         "age": 20,
16         "sex": ""
17     }
18 }

  效果如下,响应:(默认返回10条数据):

  

  2)关键字搜素数据

1 GET /test/doc/_search?q=age:20

  效果如下:

  

6、DSL搜索

  Elasticsearch提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询。

  DSL(Domain Specific Language特定领域语言)以JSON请求体的形式出现。

 1 GET /test/doc/_search
 2 
 3 #请求体
 4 {
 5     "query" : {
 6         "match" : { #match只是查询的一种
 7             "age" : 20
 8         }
 9     } 
10 }

  效果如下:

  

  实现:查询年龄大于30岁的男性用户。

  示例

  现有数据

  

  查询

 1 GET /test/doc/_search
 2 
 3 #请求体
 4 {
 5     "query": {
 6         "bool": {
 7             "filter": {
 8                 "range": {
 9                     "age": {
10                         "gt": 30
11                     }
12                 }
13             },
14             "must": {
15                 "match": {
16                     "sex": ""
17                 }
18             }
19         }
20     }
21 }

  效果

  

  全文搜索

  查询

  

7、高亮显示  

 1 POST /test/doc/_search
 2 
 3 #请求体
 4 {
 5     "query": {
 6         "match": {
 7             "name": "张三 李四"
 8         }
 9     },
10 
11     "highlight": {
12         "fields": {
13             "name": {}
14         }
15     }
16 }

  效果如下:

  

8、聚合

  在Elasticsearch中,支持聚合操作,类似SQL中的group by操作。

 1 POST /test/doc/_search
 2 
 3 #请求体
 4 {
 5     "aggs": {
 6         "all_interests": {
 7             "terms": {
 8                 "field": "age"
 9             }
10         }
11     }
12 }

  效果如下:

  

  从结果可以看出,年龄30的有2条数据,20的有一条,40的一条。

原文地址:https://www.cnblogs.com/h--d/p/13089585.html