启动 elasticsearch(脚本)、kibana(bat脚本) 和 elasticsearch-head-master(npm run start)
1、RESTful 风格
![](https://i-blog.csdnimg.cn/direct/000d8a43869e4f76b857fca815fe6dfa.png)
1.1、索引类基本操作
1.1.1、创建索引
bash
PUT /索引名/类型名/文档id
{请求体}
![](https://i-blog.csdnimg.cn/direct/372394c576904ac3a97ed0092111b0ca.png)
在 elasticsearch-head-master 查看:
![](https://i-blog.csdnimg.cn/direct/4a7678587670447c9f2e93c72f92ab57.png)
可以看到,索引 test1 被成功创建了 ,查看数据:
![](https://i-blog.csdnimg.cn/direct/eda6d62483934534b51b9e45df8b44ce.png)
1.1.2、基本数据类型
- 字符串类型
text、keyword - 数值类型
long、integer、short、byte、double、float、half float、scaled float - 日期类型
date - 布尔值类型
boolean - 二进制类型
binary
创建索引的时候可以不指定索引规则(字段类型),es 会自动判断(只不过有时候可能判断错误)
1.1.3、创建索引时指定字段类型
下面,我们创建一个索引,并指定索引规则:
![](https://i-blog.csdnimg.cn/direct/e390c223adc944eca1f52d19049991e3.png)
1.1.4、获得索引规则信息
语法:
bash
# 获得索引信息
GET 索引
# 获得文档信息
GET 索引/类型/文档id
![](https://i-blog.csdnimg.cn/direct/9b7bd00d29ef4c94a4ca3de01b0996bc.png)
1.1.5、修改数据
1)使用 PUT 覆盖
修改 /test1/type1/1 中的 age 属性为 18:
![](https://i-blog.csdnimg.cn/direct/a70eecbbeee744a3822c442100d7851d.png)
这种方法的一个缺点是,我们在覆盖的过程中可能会不小心漏掉一些字段,导致数据丢失。
2)POST 更新文档
修改 /test1/type1/1 的 name 属性为 "燕双鹰"
![](https://i-blog.csdnimg.cn/direct/42a89a30c1394e1389f3b287daa2e3bd.png)
![](https://i-blog.csdnimg.cn/direct/8f6538e2eb5b44209033636d64ff045b.png)
1.1.6、删除索引
删除 test2 索引:
![](https://i-blog.csdnimg.cn/direct/b56b03ad6bb341078c0bfa1005a27fac.png)
bash
DELETE test2
![](https://i-blog.csdnimg.cn/direct/3fd0415f5087458382146d056f7f0bc8.png)
1.2、文档操作
1.2.1、基本操作
1、PUT 插入数据
bash
PUT /lyh/user/1
{
"name": "李大喜",
"age": 25,
"desc": "只想做农民",
"tags": ["半人半鬼","神枪第一"]
}
PUT /lyh/user/2
{
"name": "谢永强",
"age": 20,
"desc": "那啥,我去趟果园",
"tags": ["窝囊强","果园天尊"]
}
PUT /lyh/user/3
{
"name": "曾泰",
"age": 45,
"desc": "大人真乃神人也",
"tags": ["舔灵"]
}
2、GET 查询数据
![](https://i-blog.csdnimg.cn/direct/55d6a26c5a344379848853b456f1df7f.png)
3、更新数据
![](https://i-blog.csdnimg.cn/direct/6b402ea5760341f996992fd131d20897.png)
4、普通文档查询
bash
GET /lyh/user/1
5、条件查询
![](https://i-blog.csdnimg.cn/direct/7e094d37c8c34be9bac52ea2c22f11a8.png)
1.2.2、复杂查询
对比上面普通 GET 查询和条件查询可以看到,使用条件查询时返回的 JSON 中有一个 _score 字段,它代表的是匹配度,也就是权重,因为 es 返回的是权重最高的数据。
score(权重)
![](https://i-blog.csdnimg.cn/direct/79c22c97f2284f92a6cdc873cfd1018b.png)
设置投影
![](https://i-blog.csdnimg.cn/direct/2c0a9fd6238d41c988ffdd1652de6c10.png)
排序
![](https://i-blog.csdnimg.cn/direct/bd2a625724fd48c4a5b514ea7bfac5f8.png)
因为原本是按照权重排序的,但是这里使用了 age 作为排序字段,所以 _score 字段为 null
分页查询
![](https://i-blog.csdnimg.cn/direct/b8d8d39aa54d46a09266920f6001e9e7.png)
条件过滤查询(bool)
and (must)
![](https://i-blog.csdnimg.cn/direct/241340ea939347818d608a8dfca769b7.png)
or (should)
![](https://i-blog.csdnimg.cn/direct/e04418b92faa424c901fc96f897bdc3c.png)
not(must_not)
![](https://i-blog.csdnimg.cn/direct/e35b2415a3be488cb6d4a557dbdaadda.png)
可以看到,这里过滤出了 age 不等于 25 的和姓名不是 "谢" (这里的 "谢" 指的是分词器分词后所包含的)的记录。
range(filter)
![](https://i-blog.csdnimg.cn/direct/d6add2e2afde457b9a72bb4416f59fc0.png)
上面,我们过滤出了所有 age >= 20 并且 <= 30 的记录
匹配多个条件
![](https://i-blog.csdnimg.cn/direct/ca44284ea5c543a3974eaf22aa49904d.png)
精确查询
term 查询是直接通过倒排索引进行精确查询的,区别于上面我们只用的 match:
- term 是精确查询
- match 会使用分词器
text 类型会被分词器解析,而 keyword 类型不会被分词器解析
![](https://i-blog.csdnimg.cn/direct/945e84a7fa694822b69e2178e4487faa.png)
测试 keyword 分词:
![](https://i-blog.csdnimg.cn/direct/60b8c23e73cd4f96af0a3f0335d7088c.png)
可以看到,使用 keyword 分词器不会把文本分开;
测试默认标准分词器
![](https://i-blog.csdnimg.cn/direct/34d5d25ded0743ffb3e14e0515a40973.png)
可以看到,使用默认标准的分词器是会把文本完全拆开的,这也是上面为什么我们可以模糊匹配的原因;
查询类型为 text 的 name 字段:
![](https://i-blog.csdnimg.cn/direct/1c1bd4e4b17c4cda8687e034c654bcb6.png)
查询字段类型为 keyword 的 desc 字段:
![](https://i-blog.csdnimg.cn/direct/c67c3af9b9554934a72360897aebcf2f.png)
所以结论就是:keyword 类型的字段不会被分词器解析。
下面我们对比一下精确查询和普通查询的区别:
![](https://i-blog.csdnimg.cn/direct/96b536a862a7479fb621d770d1c2bca9.png)
我们的 test2 索引中只有两条记录(name 分别为 "数据开发工程师" 和 "数据平台开发工程师")可以看到,当使用精确查询的时候,查询 "数据" 是查不出来的,这是因为精确查询默认会使用分词器,而标准的分词器是不支持中文的,它会把每一个中文都当做一个词,所以上面当查询 "数" 的时候才可以查出来。
![](https://i-blog.csdnimg.cn/direct/0b25749f866b48d799d7729ad98edffe.png)
可以看到,当使用普通匹配查询时, 就可以查询出所有包含该词的所有记录;
高亮查询
![](https://i-blog.csdnimg.cn/direct/bbc414ff8298460f89d3d0224190f0d5.png)
可以看到,查询出来的结果中的匹配字段被加上了 html 标签,我们也可以自定义这个标签:
![](https://i-blog.csdnimg.cn/direct/4dacdf3423e3477797169f42550fb6ab.png)
1.3、ES 集成 SpringBoot
1.3.1、ES 配置类
java
@Configuration
public class ElasticSearchClientConfig {
// <bean id="restHighLevelClient" class="org.elasticsearch.client.RestHighLevelClient">
@Bean
public RestHighLevelClient restHighLevelClient(){
return new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost",9200,"http")
)
);
}
}
1.3.2、创建索引
java
@SpringBootTest
class EsApiApplicationTests {
@Autowired
private RestHighLevelClient client;
// 索引创建
@Test
void testCreateIndex() throws IOException {
// 1. 创建索引请求
CreateIndexRequest request = new CreateIndexRequest("lyh_index");
// 2. 执行请求,返回响应
CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
System.out.println(createIndexResponse);
}
}
执行结果:
![](https://i-blog.csdnimg.cn/direct/ff7100b0c7ae443ebf31a3cf28c816e3.png)
可以看到,成功创建了一个索引(没有任何字段)
1.3.3、判断索引是否存在
java
// 判断索引是否存在
@Test
void testGetIndex() throws IOException {
GetIndexRequest request = new GetIndexRequest("lyh_index");
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
}
1.3.4、删除索引
java
// 删除索引
@Test
void testDeleteIndex() throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest("lyh_index");
AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}
1.3.5、创建文档
创建 Student 类:
java
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class Student {
private String name;
private int age;
}
导入 fastjson 并测试:
java
// 测试添加文档
@Test
void testAddDocument() throws IOException {
Student student = new Student("李元芳",20);
IndexRequest request = new IndexRequest("lyh_index");
// 索引规则
request.id("1");
request.timeout("1s");
// 放入请求
request.source(JSONValue.toJSONString(student), XContentType.JSON);
// 获取响应结果
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
System.out.println(indexResponse.toString());
System.out.println(indexResponse.status());
}
上面的代码相当于:
java
PUT /lyh_index/_doc/1
{
"name": "李元芳",
"age": 20
}
执行结果:
![](https://i-blog.csdnimg.cn/direct/94bacac4af1f4e7fbe92928afb6db334.png)
1.3.5、判断文档是否存在
java
@Test
void testExists() throws IOException {
// 相当于 GET /lyh_index/_doc/1
GetRequest getRequest = new GetRequest("lyh_index","1");
boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
System.out.println(exists);
}
1.3.6、获取文档内容
java
@Test
void testGetDocument() throws IOException {
// 相当于 GET /lyh_index/_doc/1
GetRequest getRequest = new GetRequest("lyh_index","1");
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
System.out.println(getResponse.getSourceAsString());
System.out.println(getResponse);
}
执行结果:
java
{"name":"李元芳","age":20}
{"_index":"lyh_index","_type":"_doc","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"name":"李元芳","age":20}}
1.3.7、更新文档内容
java
@Test
void testUpdateDocument() throws IOException {
UpdateRequest updateRequest = new UpdateRequest("lyh_index","1");
updateRequest.timeout("1s");
Student student = new Student("狄如燕", 20);
updateRequest.doc(JSONValue.toJSONString(student),XContentType.JSON);
client.update(updateRequest,RequestOptions.DEFAULT);
}
执行结果:
![](https://i-blog.csdnimg.cn/direct/3a826af0faea4c0fa90577188a741409.png)
1.3.8、删除文档
java
@Test
void testDeleteDocument() throws IOException {
DeleteRequest deleteRequest = new DeleteRequest("lyh_index", "2");
deleteRequest.timeout("1s");
DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(deleteResponse.status());
}
1.3.9、批量导入数据
java
@Test
void testBulkRequest() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("10s");
ArrayList<Student> students = new ArrayList<>();
students.add(new Student("谢永强",20));
students.add(new Student("谢小梅",25));
students.add(new Student("谢广坤",50));
students.add(new Student("刘能",51));
students.add(new Student("赵四",48));
students.add(new Student("王老七",52));
students.add(new Student("刘英",21));
for(int i=0;i<students.size();i++){
bulkRequest.add(new IndexRequest("lyh_index")
.id(""+(i+1))
.source(JSONValue.toJSONString(students.get(i)),XContentType.JSON)
);
BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulk.status());
}
}
![](https://i-blog.csdnimg.cn/direct/8ea9f696336e44758f3ab1ebdab42771.png)