参考文档
包括中文分词:https://www.jianshu.com/p/d2afc19cafbd
拼音搜索:https://github.com/medcl/elasticsearch-analysis-pinyin/releases?after=v7.4.2
1.导入jar包:
<properties>
<elasticsearch.version>7.2.0</elasticsearch.version>
</properties>
<!-- Elasticsearch 一定要检查关联得依赖是否一致-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<exclusions>
<!--自带es版本太低了需要排除-->
<exclusion>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</exclusion>
<exclusion>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
</exclusion>
</exclusions>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
2. ElasticSearchClientConfig高级客户端的配置
package com.unwulian.thirdserver.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author shiye
* @create 2020-07-17 16:38
*/
@Configuration
public class ElasticSearchClientConfig {
@Autowired
private EsParamConfig esParamConfig;
@Bean
public RestHighLevelClient restHighLevelClient() {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost(esParamConfig.getHost(), esParamConfig.getPort(), esParamConfig.getScheme())));
return client;
}
}
3.编写配置文件
es:
host: 127.0.0.1
port: 9200
scheme: http
default_index: community_index
timeout: 60
4. 配置文件的读取
package com.unwulian.thirdserver.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.io.Serializable;
/**
* @author shiye
* @create 2020-07-17 19:30
*/
@Configuration
@ConfigurationProperties(prefix = "es")
public class EsParamConfig implements Serializable {
/**
* 主机
*/
private String host;
/**
* 端口
*/
private int port;
/**
* http协议
*/
private String scheme;
/**
* 索引库,默认为:community_index
*/
private String default_index = "community_index";
/**
* 超时时间,到秒
*/
private int timeout;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getScheme() {
return scheme;
}
public void setScheme(String scheme) {
this.scheme = scheme;
}
public String getDefault_index() {
return default_index;
}
public void setDefault_index(String default_index) {
this.default_index = default_index;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
}
6.工具类编写,主要是配置索引,和分词
package com.unwulian.thirdserver.util;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import java.io.IOException;
/**
* ES的配置文件
*
* @author shiye
* @create 2020-07-20 11:46
*/
public class EsPropertyConfigUtil {
/**
* 索引设置
* @param request
* @return
*/
public static CreateIndexRequest indexSetting(CreateIndexRequest request) {
Settings.Builder builder = Settings.builder();
builder.put("analysis.tokenizer.my_pinyin.type", "pinyin");
/**********中文转拼音的配置**********/
//keep_first_letter启用此选项时,例如:刘德华> ldh,默认值:true
builder.put("analysis.tokenizer.my_pinyin.keep_first_letter", true);
//limit_first_letter_length 设置first_letter结果的最大长度,默认值:16
builder.put("analysis.tokenizer.my_pinyin.limit_first_letter_length", 16);
//keep_full_pinyin当启用该选项,例如:刘德华> [ liu,de,hua],默认值:true
builder.put("analysis.tokenizer.my_pinyin.keep_full_pinyin", true);
//keep_joined_full_pinyin启用此选项时,例如:刘德华> [ liudehua],默认值:false
builder.put("analysis.tokenizer.my_pinyin.keep_joined_full_pinyin", false);
//keep_none_chinese 将非中文字母或数字保留在结果中,默认值:true
builder.put("analysis.tokenizer.my_pinyin.keep_none_chinese", true);
//keep_none_chinese_together 保持非中国信一起,默认值:true,如:DJ音乐家- > DJ,yin,yue,jia,当设置为false,例如:DJ音乐家- > D,J,yin,yue,jia,注意:keep_none_chinese应先启用
builder.put("analysis.tokenizer.my_pinyin.keep_none_chinese_together", true);
//keep_none_chinese_in_first_letter 将非中文字母保留在首字母中,例如:刘德华AT2016-> ldhat2016,默认值:true
builder.put("analysis.tokenizer.my_pinyin.keep_none_chinese_in_first_letter", false);
//keep_none_chinese_in_joined_full_pinyin 将非中文字母保留在拼音中,例如:刘德华2016-> liudehua2016,默认值:false
builder.put("analysis.tokenizer.my_pinyin.keep_none_chinese_in_joined_full_pinyin", true);
//none_chinese_pinyin_tokenize 打破非中国信成单独的拼音项,如果他们是拼音,默认值:true,如:liudehuaalibaba13zhuanghan- > liu,de,hua,a,li,ba,ba,13,zhuang,han,注意: keep_none_chinese和keep_none_chinese_together应首先启用
builder.put("analysis.tokenizer.my_pinyin.none_chinese_pinyin_tokenize", true);
//keep_original 启用此选项后,还将保留原始输入,默认值:false
builder.put("analysis.tokenizer.my_pinyin.keep_original", true);
//lowercase 小写非中文字母,默认:true
builder.put("analysis.tokenizer.my_pinyin.lowercase", true);
//trim_whitespace 默认值:true
builder.put("analysis.tokenizer.my_pinyin.trim_whitespace", true);
//remove_duplicated_term 启用此选项后,将删除重复的术语以保存索引,例如:de的> de,默认值:false,注意:与位置相关的查询可能会受到影响
builder.put("analysis.tokenizer.my_pinyin.remove_duplicated_term", true);
//ignore_pinyin_offset 在6.0之后,严格限制偏移量,不允许使用重叠的标记,使用此参数时,忽略偏移量将允许使用重叠的标记,请注意,所有与位置相关的查询或突出显示都将变为错误,您应使用多个字段并为不同的字段指定不同的设置查询目的。如果需要偏移量,请将其设置为false。默认值:true。
builder.put("analysis.tokenizer.my_pinyin.ignore_pinyin_offset", true);
//keep_separate_first_letter启用该选项时,将保留第一个字母分开,例如:刘德华> l,d,h,默认:假的,注意:查询结果也许是太模糊,由于长期过频
builder.put("analysis.tokenizer.my_pinyin.keep_separate_first_letter", true);
/******************当前索引的分词器配置*******************/
builder.put("analysis.analyzer.pinyin_analyzer.tokenizer", "my_pinyin");
request.settings(builder);
return request;
}
/**
* 社区服务ES mapping 的 设置
*
* @param request
* @return
*/
public static CreateIndexRequest indexMappingCommunity(CreateIndexRequest request) throws IOException {
XContentBuilder builder = null;
builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.startObject("properties");
{
builder.startObject("coId");
{
builder.field("type", "text");
}
builder.endObject();
builder.startObject("coName");
{
builder.field("type", "text");
builder.field("analyzer", "pinyin_analyzer");
}
builder.endObject();
builder.startObject("cityId");
{
builder.field("type", "text");
}
builder.endObject();
builder.startObject("cityName");
{
builder.field("type", "text");
builder.field("analyzer", "pinyin_analyzer");
}
builder.endObject();
builder.startObject("areaId");
{
builder.field("type", "text");
}
builder.endObject();
builder.startObject("areaName");
{
builder.field("type", "text");
builder.field("analyzer", "pinyin_analyzer");
}
builder.endObject();
}
builder.endObject();
}
builder.endObject();
request.mapping(builder);
return request;
}
}
7. 测试代码
package com.unwulian.thirdserver;
import com.alibaba.fastjson.JSON;
import com.unwulian.common.thirdentity.CommunityEntity;
import org.apache.http.HttpHost;
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.RestClient;
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.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author shiye
* @create 2020-07-17 17:01
*/
public class EsApplicationTest {
//构建对象
public RestHighLevelClient restHighLevelClient() {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1", 9200, "http")));
return client;
}
//创建索引
@Test
public void testCreateIndex() throws IOException {
RestHighLevelClient client = restHighLevelClient();
try {
//1.创建索引请求
CreateIndexRequest request = new CreateIndexRequest("shiye_index");
//2. 客户端执行请求
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
System.out.println(response);
} finally {
client.close();
}
}
//测试索引是否存在
@Test
public void testExitIndex() throws IOException {
RestHighLevelClient client = restHighLevelClient();
try {
//1.创建索引请求
GetIndexRequest request = new GetIndexRequest("shiye_index");
//2. 客户端执行请求
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println("是否存在:" + exists);
} finally {
client.close();
}
}
//删除索引
@Test
public void testDeleteIndex() throws IOException {
RestHighLevelClient client = restHighLevelClient();
try {
//1.创建索引请求
DeleteIndexRequest request = new DeleteIndexRequest("shiye_index");
//2. 客户端执行请求
AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println("是否删除成功:" + response.isAcknowledged());
} finally {
client.close();
}
}
//测试添加文档
@Test
public void testAddDoc() throws IOException {
CommunityEntity communityEntity = new CommunityEntity();
communityEntity.setCoId("EQ001");
communityEntity.setCoName("宇宙天下");
communityEntity.setAreaId("A001");
communityEntity.setAreaName("蜀山区");
communityEntity.setCityId("A002");
communityEntity.setCityName("合肥市");
RestHighLevelClient client = restHighLevelClient();
try {
//1.创建索引请求
IndexRequest request = new IndexRequest("shiye_index");
// 规则 : put /shiye_index/_doc/1
request.id(communityEntity.getCoId());
request.timeout(TimeValue.timeValueSeconds(1));
request.timeout("1s");
//2. 客户端执行请求
request.source(JSON.toJSONString(communityEntity), XContentType.JSON);
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
System.out.println("对象是否创建成功:" + response.status());
} finally {
client.close();
}
}
//获取上面创建的索引
@Test
public void getDocIndex() throws IOException {
RestHighLevelClient client = restHighLevelClient();
try {
//1.创建索引请求
GetRequest request = new GetRequest("shiye_index", "EQ001");
// 规则 : get /shiye_index/_doc/1
//2. 客户端执行请求
GetResponse response = client.get(request, RequestOptions.DEFAULT);
System.out.println("获取到的对象为:" + response.getSource());
} finally {
client.close();
}
}
//跟新文档记录
@Test
public void testupdateDocIndex() throws IOException {
CommunityEntity communityEntity = new CommunityEntity();
communityEntity.setCoId("EQ001");
communityEntity.setCoName("宇宙天下9999");
communityEntity.setAreaId("A001999");
communityEntity.setAreaName("蜀山区9999");
communityEntity.setCityId("A002999");
communityEntity.setCityName("合肥市9999");
RestHighLevelClient client = restHighLevelClient();
try {
//1.创建索引请求
UpdateRequest updateRequest = new UpdateRequest("shiye_index", "EQ001");
// 规则 : put /shiye_index/_doc/1
updateRequest.id(communityEntity.getCoId());
updateRequest.timeout(TimeValue.timeValueSeconds(1));
updateRequest.timeout("1s");
updateRequest.doc(JSON.toJSONString(communityEntity), XContentType.JSON);
//2. 客户端执行请求
UpdateResponse response = client.update(updateRequest, RequestOptions.DEFAULT);
System.out.println("对象是否跟新成功:" + response.status());
} finally {
client.close();
}
}
//删除文档记录
@Test
public void testDeleteDoc() throws IOException {
RestHighLevelClient client = restHighLevelClient();
try {
DeleteRequest request = new DeleteRequest("shiye_index", "EQ001");
request.timeout("1s");
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
System.out.println("是否删除成功" + response.status());
} finally {
client.close();
}
}
//批量导入数据
@Test
public void testBulkRequest() throws IOException {
RestHighLevelClient client = restHighLevelClient();
try {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("1s");
List<CommunityEntity> list = new ArrayList<>();
list.add(new CommunityEntity("EQ001", "宇宙天下1", "A002", "合肥市", "A001", "蜀山区1"));
list.add(new CommunityEntity("EQ002", "宇宙天下2", "A002", "合肥市", "A001", "蜀山区1"));
list.add(new CommunityEntity("EQ003", "宇宙天下3", "A002", "合肥市", "A001", "蜀山区1"));
list.add(new CommunityEntity("EQ004", "宇宙天下4", "A002", "合肥市", "A001", "蜀山区1"));
list.add(new CommunityEntity("EQ005", "宇宙天下5", "A002", "合肥市", "A001", "蜀山区1"));
list.add(new CommunityEntity("EQ006", "宇宙天下6", "A002", "合肥市", "A001", "蜀山区1"));
//准备批量请求数据
for (CommunityEntity communityEntity : list) {
bulkRequest.add(
new IndexRequest("shiye_index")
.id(communityEntity.getCoId())
.source(JSON.toJSONString(communityEntity), XContentType.JSON)
);
}
BulkResponse response = client.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println("批量创建是否成功:" + response.status());
} finally {
client.close();
}
}
//查询
@Test
public void testSearchDoc() throws IOException {
RestHighLevelClient client = restHighLevelClient();
try {
SearchRequest request = new SearchRequest("shiye_index");
//构建搜索条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//QueryBuilders.termQuery 全匹配查询
MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("eqName", "宇宙");
sourceBuilder.query(queryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
request.source(sourceBuilder);
SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
System.out.println("命中的数据为:" + searchResponse.getHits());
System.out.println("===============================");
for (SearchHit documentFields : searchResponse.getHits().getHits()) {
System.out.println(documentFields.getSourceAsMap());
}
} finally {
client.close();
}
}
}