一、Elasticsearch
1.elasticsearch官网下载
以下使用版本为7.6.1,学习自b站up 遇见狂神说的 【狂神说Java】ElasticSearch7.6.x最新完整教程通俗易懂
2.下载es head插件
可视化
https://github.com/mobz/elasticsearch-head/
npm安装并启动
在文件夹下面cmd (或者cd到对应文件夹),然后nmp install 再然后 npm run start
3.解决跨域问题
elasticsearch.yml配置文件末尾追加
http.cors.enabled: true
http.cors.allow-origin: "*"
4.kibana下载
版本对应,官网下载
汉化:kibana.yml文件添加:
i18n.locale: "zh-CN"
启动
5.添加ik分词器
https://github.com/medcl/elasticsearch-analysis-ik/releases
版本对应 git搜索下载
解压到plugins目录下
6.kibana运行编写
ik_smart :最少切分
ik_max_word: 最细粒度划分
执行代码
GET _analyze
{
"analyzer": "ik_max_word",
"text": "超级无敌大雪球"
}
执行结果
{
"tokens" : [
{
"token" : "超级",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "无敌",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "大雪",
"start_offset" : 4,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "雪球",
"start_offset" : 5,
"end_offset" : 7,
"type" : "CN_WORD",
"position" : 3
}
]
}
执行代码:
GET _analyze
{
"analyzer": "ik_smart",
"text": "超级无敌大雪球"
}
执行结果
{
"tokens" : [
{
"token" : "超级",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "无敌",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "大",
"start_offset" : 4,
"end_offset" : 5,
"type" : "CN_CHAR",
"position" : 2
},
{
"token" : "雪球",
"start_offset" : 5,
"end_offset" : 7,
"type" : "CN_WORD",
"position" : 3
}
]
}
7.ik分词器配置自己需要的词
在ik目录下的config文件中添加 name.dic 字典,添加自己需要的词
打开xml配置文件
在中添加刚刚配置的字典
name.dic
8.创建索引
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l91Re8j6-1617267622861)(https://i.loli.net/2021/04/01/1MK9vu6c8iStmlg.png)]
PUT /test1/type1/1
{
"name": "雪人",
"age": "3"
}
test1:索引名
type1:类型名,可省略
1:文档id
执行结果:
#! Deprecation: [types removal] Specifying types in document index requests is deprecated, use the typeless endpoints instead (/{index}/_doc/{id}, /{index}/_doc, or /{index}/_create/{id}).
{
"_index" : "test1",
"_type" : "type1",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 3
}
mappings:映射规则
9.获得具体信息:
GET 索引名:GET test1
10,修改,修改成功后version发生变化
(1).使用put,不建议,因为要把所有的内容都写完,不然会成为空白,因为执行的是覆盖操作。
PUT /test2/_doc/1
{
"name": "雪人",
"age": "3"
}
结果:
{
"_index" : "test2",
"_type" : "_doc",
"_id" : "1",
"_version" : 3,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}
(2)POST
POST /test2/_doc/1/_update
{
"doc":{
"name": "泥人"
}
}
结果:
#! Deprecation: [types removal] Specifying types in document update requests is deprecated, use the endpoint /{index}/_update/{id} instead.
{
"_index" : "test2",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
11.删除
DELETE /test2/_doc/1
删除后无数据
或者
DELETE test2
删除整个索引
12.简单的查询
GET test2/_doc/_search?q=age:4
结果:
#! Deprecation: [types removal] Specifying types in search requests is deprecated.
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.4700036,
"hits" : [
{
"_index" : "test2",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.4700036,
"_source" : {
"name" : "泥人",
"age" : "4"
}
},
{
"_index" : "test2",
"_type" : "_doc",
"_id" : "3",
"_score" : 0.4700036,
"_source" : {
"name" : "雪人",
"age" : "4"
}
}
]
}
}
13.复杂搜索
GET test2/_doc/_search
{
"query":{
"match":{
"name":"雪人"
}
},
"_source":["age","desc"]
}
结果
#! Deprecation: [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : 0.46203545,
"hits" : [
{
"_index" : "test2",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.46203545,
"_source" : {
"age" : "3"
}
},
{
"_index" : "test2",
"_type" : "_doc",
"_id" : "3",
"_score" : 0.46203545,
"_source" : {
"age" : "4"
}
},
{
"_index" : "test2",
"_type" : "_doc",
"_id" : "5",
"_score" : 0.46203545,
"_source" : {
"age" : "3"
}
},
{
"_index" : "test2",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.10536051,
"_source" : {
"age" : "4"
}
}
]
}
}
排序:
GET test2/_doc/_search
{
"query":{
"match":{
"name":"雪人"
}
},
"sort":[
{
"age":{
"order":"desc"
}
}
]
}
分页:
GET test2/_doc/_search
{
"query":{
"match":{
"name":"雪人"
}
},
"from":0,
"size":1
}
判断:
必须
GET test2/_doc/_search
{
"query":{
"bool":{
"must":[
{
"match":{
"name":"水人"
}
},
{
"match":{
"age":3
}
}
]
}
},
"from":0,
"size":1
}
or满足一个就可以
GET test2/_doc/_search
{
"query":{
"bool":{
"should":[
{
"match":{
"name":"水人"
}
},
{
"match":{
"age":3
}
}
]
}
},
"from":0,
"size":1
}
not不是的
GET test2/_doc/_search
{
"query":{
"bool":{
"must_not":[
{
"match":{
"name":"水人"
}
},
{
"match":{
"age":3
}
}
]
}
},
"from":0,
"size":1
}
过滤器:
GET test2/_doc/_search
{
"query":{
"bool":{
"must_not":[
{
"match":{
"name":"水人"
}
},
{
"match":{
"age":3
}
}
],
"filter":{
"range":{
"age":{
"lt":10
}
}
}
}
},
"from":0,
"size":1
}
gt 大于
get 大于等于
lt 小于
lte 小于等于
多个条件:用空格隔开
GET test2/_doc/_search
{
"query":{
"match":{
"tags":"金 火"
}
}
}
14.精确查询
term:直接查询精确的
match,使用分词器解析
text:可以被分词器解析
keyword:不能被解析
多个条件精确查找:
高亮:
GET test2/_doc/_search
{
"query":{
"match":{
"name":"雪人"
}
},
"highlight":{
"fields":{
"name":{}
}
}
}
15.集成Springboot
1.加入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.li</groupId>
<artifactId>li-es-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>li-es-api</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<elasticsearch.version>7.6.1</elasticsearch.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.74</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
注意版本与本地elasticsearch一致
16.创建config文件
package com.li.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Mr.li
* @program: li-es-api
* @description elasticsearch
* @create 2021-03-29
**/
@Configuration
public class ElasticsearchClientConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient restHighLevelClient=new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1",9200,"http")//构造器,9200 ES端口
)
);
return restHighLevelClient;
}
}
17.测试
package com.li;
import com.alibaba.fastjson.JSON;
import com.li.pojo.User;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
@SpringBootTest
class LiEsApiApplicationTests {
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient restHighLevelClient;
//创建索引
@Test
void testCreatIndex() throws IOException {
//创建索引请求
CreateIndexRequest request = new CreateIndexRequest("li_index");
//客户端执行请求
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
System.out.println(createIndexResponse);
}
//获取索引
@Test
void testExistIndex() throws IOException{
GetIndexRequest request=new GetIndexRequest("li_index");
boolean exists=restHighLevelClient.indices().exists(request,RequestOptions.DEFAULT);
System.out.println(exists);
}
//删除索引
@Test
void testDEleteIndex() throws IOException{
DeleteIndexRequest request=new DeleteIndexRequest("li_index");
AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(delete);
}
@Test
void testAddDocument() throws IOException {
//创建对象
User user=new User("li",18);
//创建请求
IndexRequest request=new IndexRequest("li_index");
//规则put /li_index/_doc/1
request.id("1");
request.timeout(TimeValue.timeValueSeconds(1));
request.timeout("1s");//两种一样,可以不写
//将我们的数据放入请求
request.source(JSON.toJSONString(user), XContentType.JSON);
//客户端发送请求
IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);
System.out.println(indexResponse.toString());
System.out.println(indexResponse.status());
}
//判断文档是否存在 get /li_index/doc/1
@Test
void testIsExists() throws IOException {
GetRequest getRequest=new GetRequest("li_index","1");
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
System.out.println(exists);
}
//获取文档信息
@Test
void testGetRequest() throws IOException {
GetRequest getRequest=new GetRequest("li_index","1");
GetResponse getResponse=restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
System.out.println(getResponse.getSourceAsString());//打印文档
System.out.println(getResponse);//返回全部
}
//更新文档信息
@Test
void testUpdateRequest() throws IOException {
UpdateRequest updateRequest=new UpdateRequest("li_index","1");
updateRequest.timeout("1s");
User user=new User("li",20);
updateRequest.doc(JSON.toJSONString(user),XContentType.JSON);
UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
System.out.println(updateResponse.status());
}
//删除文档信息
@Test
void testDeleteRequest() throws IOException {
DeleteRequest deleteRequest = new DeleteRequest("li_index","3");
DeleteResponse delete = restHighLevelClient.delete(deleteRequest,RequestOptions.DEFAULT);
System.out.println(delete.status());
}
//批量插入数据
@Test
void testBulkRequest() throws IOException {
BulkRequest bulkRequest=new BulkRequest();
bulkRequest.timeout("10s");
ArrayList<User> userList=new ArrayList<>();
userList.add(new User("li1",22));
userList.add(new User("li2",22));
userList.add(new User("li3",22));
userList.add(new User("li4",22));
userList.add(new User("li5",22));
userList.add(new User("li6",22));
for (int i = 0; i < userList.size(); i++) {
//批量更新和批量删除修改对应的请求
bulkRequest.add(
new IndexRequest("li_index")
.id(""+(i+1))
.source(JSON.toJSONString(userList),XContentType.JSON)
);
}
BulkResponse bulkItemResponses=restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
System.out.println(bulkItemResponses.hasFailures());//返回false代表成功
}
//查询
@Test
void testSearch() throws IOException {
SearchRequest searchRequest=new SearchRequest("li_index");
//构建搜索条件其
SearchSourceBuilder sourceBuilder=new SearchSourceBuilder();
sourceBuilder.highlighter();
//查询条件,我们可以使用QueryBuildes 工具实现
// QueryBuilders.termQuery(); 精确
// QueryBuilders.matchAllQuery(); 匹配所有
TermQueryBuilder termQueryBuilder=QueryBuilders.termQuery("name","li1");
sourceBuilder.query(termQueryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(sourceBuilder);
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(search.getHits()));
for (SearchHit documentFields : search.getHits().getHits()) {
System.out.println(documentFields.getSourceAsMap());
}
}
}