【Elasticsearch系列五】Java API
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
- 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老
- 导航
- 檀越剑指大厂系列:全面总结 java 核心技术,jvm,并发编程 redis,kafka,Spring,微服务等
- 常用开发工具系列:常用的开发工具,IDEA,Mac,Alfred,Git,typora 等
- 数据库系列:详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
- 新空间代码工作室:提供各种软件服务,承接各种毕业设计,毕业论文等
- 懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
- 数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂
非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨
博客目录
- 1.document
- 1.pom
- 2.yaml
- 3.config
- 4.get
- 5.add
- 6.update
- 7.delete
- 8.bulk
- 2.index
- 1.创建索引
- 2.删除索引
- 3.是否存在索引
- 4.关闭索引
- 5.打开索引
- 3.search
- 1.all
- 2.page
- 3.ids
- 4.match
- 5.term
- 6.multi_match
- 7.bool
- 8.filter
- 9.sort
- 4.sql 功能
- 5.学成在线站内搜索模块
- 1.mysql 导入学生数据
- 2.创建索引 xc_course
- 3.创建映射
- 4.logstash 创建模板文件
- 5.logstash 配置 mysql.conf
- 6.启动
- 7.后端代码
- 7.1.Controller
- 7.2.service
代码地址
1.document
1.pom
<dependencies>
<!--es客户端-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<!-- low:偏向底层。high :高級封装。足够。-->
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.3.0</version>
<exclusions>
<exclusion>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<version>2.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
</dependencies>
2.yaml
spring:
application:
name: search-service
kwan:
elasticsearch:
hostlist: 47.119.162.180:9200 #多个节点用逗号分隔
3.config
@Configuration
public class ElasticsearchConfig {
@Value("${kwan.elasticsearch.hostlist}")
private String hostlist;
@Bean(destroyMethod = "close")
public RestHighLevelClient restHighLevelClient() {
String[] split = hostlist.split(",");
HttpHost[] httpHostsArray = new HttpHost[split.length];
for (int i = 0; i < split.length; i++) {
String item = split[i];
httpHostsArray[i] = new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":")[1]), "http");
}
return new RestHighLevelClient(RestClient.builder(httpHostsArray));
}
}
4.get
@Slf4j
@SpringBootTest(classes = SearchApplication.class)
@RunWith(SpringRunner.class)
public class TestDocument_01_get {
@Autowired
RestHighLevelClient client;
@Test
public void testGet() throws IOException {
//构建请求
GetRequest getRequest = new GetRequest("test_post", "1");
//添加可选参数
String[] includes = new String[]{"id", "comment"};
String[] excludes = Strings.EMPTY_ARRAY;
FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes);
getRequest.fetchSourceContext(fetchSourceContext);
//同步查询
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
//获取结果
if (getResponse.isExists()) {
log.info(getResponse.getId());
log.info(String.valueOf(getResponse.getVersion()));
log.info(getResponse.getSourceAsString());//以string获取数据
log.info(String.valueOf(getResponse.getSourceAsBytes()));以Bytes获取数据
log.info(String.valueOf(getResponse.getSourceAsMap()));//以Map获取数据
} else {
log.info("数据不存在");
}
}
}
@Test
public void testGet() {
//构建请求
GetRequest getRequest = new GetRequest("test_post", "1");
//添加可选参数
String[] includes = new String[]{"id", "title"};
String[] excludes = Strings.EMPTY_ARRAY;
FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes);
getRequest.fetchSourceContext(fetchSourceContext);
//设置监听器
ActionListener<GetResponse> listener = new ActionListener<GetResponse>() {
//成功时
public void onResponse(GetResponse getResponse) {
log.info(getResponse.getId());
log.info(String.valueOf(getResponse.getVersion()));
log.info(getResponse.getSourceAsString());
}
//失败时
public void onFailure(Exception e) {
e.printStackTrace();
log.info("数据获取异常");
}
};
//异步查询
client.getAsync(getRequest, RequestOptions.DEFAULT, listener);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
5.add
@Test
public void testAdd() throws IOException {
//构建请求
IndexRequest request = new IndexRequest("test_post");
request.id("5");
//构建文档数据
String jsonString = "{\n" +
" \"user\":\"tomas\",\n" +
" \"postDate\":\"2019-07-18\",\n" +
" \"message\":\"trying out es1\"\n" +
"}";
request.source(jsonString, XContentType.JSON);
//同步
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
//获取结果
log.info(indexResponse.getIndex());
log.info(indexResponse.getId());
log.info(String.valueOf(indexResponse.getResult()));
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("CREATE" + result);
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("UPDATED" + result);
} else {
log.info("其他操作");
}
//获取分片信息
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
log.info("处理成功的分片数少于总分片!");
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();//每一个错误的原因
log.info(reason);
}
}
}
@Test
public void testAdd() throws IOException {
//构建请求
IndexRequest request = new IndexRequest("test_post");
request.id("6");
//构建文档数据
Map<String, Object> jsonMap = new HashMap<String, Object>();
jsonMap.put("user", "tomas");
jsonMap.put("postDate", "2019-07-18");
jsonMap.put("message", "trying out es1");
request.source(jsonMap);
//同步执行
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
//获取结果
log.info(indexResponse.getIndex());
log.info(indexResponse.getId());
log.info(String.valueOf(indexResponse.getResult()));
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("CREATE" + result);
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("UPDATED" + result);
}
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
log.info("处理成功的分片数少于总分片!");
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();//每一个错误的原因
log.info(reason);
}
}
}
@Test
public void testAdd() throws IOException {
//构建请求
IndexRequest request = new IndexRequest("test_post");
request.id("7");
//构建文档数据
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.field("user", "tomas");
builder.field("message", "trying out es1");
builder.timeField("postDate", "2019-07-18");
}
builder.endObject();
request.source(builder);
//同步执行
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
//获取结果
log.info(indexResponse.getIndex());
log.info(indexResponse.getId());
log.info(String.valueOf(indexResponse.getResult()));
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("CREATE" + result);
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("UPDATED" + result);
}
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
log.info("处理成功的分片数少于总分片!");
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();//每一个错误的原因
log.info(reason);
}
}
}
@Test
public void testAdd() throws IOException {
//构建请求
IndexRequest request = new IndexRequest("test_post");
request.id("9");
//构建文档数据
request.source("user", "tomas",
"message", "trying out es1",
"postDate", "2019-07-18");
//同步执行
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
//获取结果
log.info(indexResponse.getIndex());
log.info(indexResponse.getId());
log.info(String.valueOf(indexResponse.getResult()));
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("CREATE" + result);
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("UPDATED" + result);
}
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
log.info("处理成功的分片数少于总分片!");
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();//每一个错误的原因
log.info(reason);
}
}
}
@Test
public void testAdd() throws IOException {
//构建请求
IndexRequest request = new IndexRequest("test_post");
request.id("10");
//构建文档数据
String jsonString = "{\n" +
" \"user\":\"tomas\",\n" +
" \"postDate\":\"2019-07-18\",\n" +
" \"message\":\"trying out es1\"\n" +
"}";
request.source(jsonString, XContentType.JSON);
//设置超时时间
request.timeout("1s");
request.timeout(TimeValue.timeValueSeconds(1));
//手动维护版本号
request.version(4);
request.versionType(VersionType.EXTERNAL);
//同步执行
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
//获取结果
log.info(indexResponse.getIndex());
log.info(indexResponse.getId());
log.info(String.valueOf(indexResponse.getResult()));
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("CREATE" + result);
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("UPDATED" + result);
}
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
log.info("处理成功的分片数少于总分片!");
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();//每一个错误的原因
log.info(reason);
}
}
}
6.update
@Test
public void testUpdate() throws IOException {
//创建请求
UpdateRequest request = new UpdateRequest("test_post", "5");
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put("user", "tomas Lee");
request.doc(jsonMap);
request.timeout("1s");
request.retryOnConflict(3);//重试次数
//同步执行
UpdateResponse updateResponse = client.update(request, RequestOptions.DEFAULT);
//获取结果
updateResponse.getId();
updateResponse.getIndex();
//判断结果
if (updateResponse.getResult() == DocWriteResponse.Result.CREATED) {
DocWriteResponse.Result result = updateResponse.getResult();
log.info("CREATED:" + result);
} else if (updateResponse.getResult() == DocWriteResponse.Result.UPDATED) {
DocWriteResponse.Result result = updateResponse.getResult();
log.info("UPDATED:" + result);
} else if (updateResponse.getResult() == DocWriteResponse.Result.DELETED) {
DocWriteResponse.Result result = updateResponse.getResult();
log.info("DELETED:" + result);
} else if (updateResponse.getResult() == DocWriteResponse.Result.NOOP) {
//没有操作
DocWriteResponse.Result result = updateResponse.getResult();
log.info("NOOP:" + result);
}
}
7.delete
@Test
public void testDelete() throws IOException {
//创建请求
DeleteRequest request = new DeleteRequest("test_post", "3");
//执行
DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);
//获取结果
deleteResponse.getId();
deleteResponse.getIndex();
DocWriteResponse.Result result = deleteResponse.getResult();
log.info(result.toString());
}
8.bulk
@Test
public void testBulk() throws IOException {
//创建请求
BulkRequest request = new BulkRequest();
request.add(new IndexRequest("post").id("1").source(XContentType.JSON, "field", "1"));
request.add(new IndexRequest("post").id("2").source(XContentType.JSON, "field", "2"));
request.add(new UpdateRequest("post", "1").doc(XContentType.JSON, "field", "3"));
request.add(new DeleteRequest("post").id("2"));
//执行
BulkResponse bulkResponse = client.bulk(request, RequestOptions.DEFAULT);
//获取结果
for (BulkItemResponse itemResponse : bulkResponse) {
DocWriteResponse response = itemResponse.getResponse();
switch (itemResponse.getOpType()) {
case INDEX:
IndexResponse indexResponse = (IndexResponse) response;
log.info("INDEX:" + indexResponse.getResult());
break;
case CREATE:
IndexResponse createResponse = (IndexResponse) response;
log.info("CREATE:" + createResponse.getResult());
break;
case UPDATE:
UpdateResponse updateResponse = (UpdateResponse) response;
log.info("UPDATE:" + updateResponse.getResult());
break;
case DELETE:
DeleteResponse deleteResponse = (DeleteResponse) response;
log.info("DELETE:" + deleteResponse.getResult());
break;
}
}
}
2.index
1.创建索引
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestIndex_01_Create {
@Autowired
private RestHighLevelClient client;
//创建索引
@Test
public void testCreateIndex() throws IOException {
// PUT /my_index
// {
// "settings": {
// "number_of_shards": 1,
// "number_of_replicas": 1
// },
// "mappings": {
// "properties": {
// "field1":{
// "type": "text"
// },
// "field2":{
// "type": "text"
// }
// }
// },
// "aliases": {
// "default_index": {}
// }
// }
//创建索引对象
CreateIndexRequest createIndexRequest = new CreateIndexRequest("itheima_book");
//设置参数
createIndexRequest.settings(Settings.builder().put("number_of_shards", "1").put("number_of_replicas", "0"));
//指定映射1
createIndexRequest.mapping(" {\n" +
" \t\"properties\": {\n" +
" \"name\":{\n" +
" \"type\":\"keyword\"\n" +
" },\n" +
" \"description\": {\n" +
" \"type\": \"text\"\n" +
" },\n" +
" \"price\":{\n" +
" \"type\":\"long\"\n" +
" },\n" +
" \"pic\":{\n" +
" \"type\":\"text\",\n" +
" \"index\":false\n" +
" }\n" +
" \t}\n" +
"}", XContentType.JSON);
//设置别名
createIndexRequest.alias(new Alias("itheima_index_new"));
// 额外参数
//设置超时时间
createIndexRequest.setTimeout(TimeValue.timeValueMinutes(2));
//设置主节点超时时间
createIndexRequest.setMasterTimeout(TimeValue.timeValueMinutes(1));
//在创建索引API返回响应之前等待的活动分片副本的数量,以int形式表示
createIndexRequest.waitForActiveShards(ActiveShardCount.from(2));
createIndexRequest.waitForActiveShards(ActiveShardCount.DEFAULT);
//操作索引的客户端
IndicesClient indices = client.indices();
//执行创建索引库
CreateIndexResponse createIndexResponse = indices.create(createIndexRequest, RequestOptions.DEFAULT);
//得到响应
boolean acknowledged = createIndexResponse.isAcknowledged();
//得到响应 指示是否在超时前为索引中的每个分片启动了所需数量的碎片副本
boolean shardsAcknowledged = createIndexResponse.isShardsAcknowledged();
System.out.println("acknowledged:" + acknowledged);
System.out.println("shardsAcknowledged:" + shardsAcknowledged);
}
}
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestIndex_04_Async {
@Autowired
private RestHighLevelClient client;
//创建索引异步方式
@Test
public void testCreateIndexAsync() {
//创建索引对象
CreateIndexRequest createIndexRequest = new CreateIndexRequest("itheima_book");
//设置参数
createIndexRequest.settings(Settings.builder().put("number_of_shards", "1").put("number_of_replicas", "0"));
//指定映射1
createIndexRequest.mapping(" {\n" +
" \t\"properties\": {\n" +
" \"name\":{\n" +
" \"type\":\"keyword\"\n" +
" },\n" +
" \"description\": {\n" +
" \"type\": \"text\"\n" +
" },\n" +
" \"price\":{\n" +
" \"type\":\"long\"\n" +
" },\n" +
" \"pic\":{\n" +
" \"type\":\"text\",\n" +
" \"index\":false\n" +
" }\n" +
" \t}\n" +
"}", XContentType.JSON);
//设置别名
createIndexRequest.alias(new Alias("itheima_index_new"));
// 额外参数
//设置超时时间
createIndexRequest.setTimeout(TimeValue.timeValueMinutes(2));
//设置主节点超时时间
createIndexRequest.setMasterTimeout(TimeValue.timeValueMinutes(1));
//在创建索引API返回响应之前等待的活动分片副本的数量,以int形式表示
createIndexRequest.waitForActiveShards(ActiveShardCount.from(2));
createIndexRequest.waitForActiveShards(ActiveShardCount.DEFAULT);
//操作索引的客户端
IndicesClient indices = client.indices();
//执行创建索引库
ActionListener<CreateIndexResponse> listener = new ActionListener<CreateIndexResponse>() {
@Override
public void onResponse(CreateIndexResponse createIndexResponse) {
//得到响应(全部)
boolean acknowledged = createIndexResponse.isAcknowledged();
//得到响应 指示是否在超时前为索引中的每个分片启动了所需数量的碎片副本
boolean shardsAcknowledged = createIndexResponse.isShardsAcknowledged();
System.out.println("acknowledged:" + acknowledged);
System.out.println("shardsAcknowledged:" + shardsAcknowledged);
}
@Override
public void onFailure(Exception e) {
e.printStackTrace();
}
};
client.indices().createAsync(createIndexRequest, RequestOptions.DEFAULT, listener);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2.删除索引
@Test
public void testDeleteIndex() throws IOException {
//创建删除索引请求
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("itheima_book");
// 执行
AcknowledgedResponse delete = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
//得到相应
boolean acknowledged = delete.isAcknowledged();
System.out.println("acknowledged:" + acknowledged);
}
3.是否存在索引
@Test
public void testExistIndex() throws IOException {
GetIndexRequest request = new GetIndexRequest("itheima_book");
//参数
request.local(false);//从主节点返回本地索引信息状态
request.humanReadable(true);//以适合人类的格式返回
request.includeDefaults(false);//是否返回每个索引的所有默认配置
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println("exists:" + exists);
}
4.关闭索引
@Test
public void testCloseIndex() throws IOException {
CloseIndexRequest request = new CloseIndexRequest("itheima_book");
AcknowledgedResponse close = client.indices().close(request, RequestOptions.DEFAULT);
boolean acknowledged = close.isAcknowledged();
System.out.println("acknowledged:" + acknowledged);
}
5.打开索引
@Test
public void testOpenIndex() throws IOException {
OpenIndexRequest request = new OpenIndexRequest("itheima_book");
OpenIndexResponse open = client.indices().open(request, RequestOptions.DEFAULT);
boolean acknowledged = open.isAcknowledged();
System.out.println("acknowledged:" + acknowledged);
}
3.search
1.all
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestSearch_01_all {
@Autowired
RestHighLevelClient client;
@Test
public void testSearchAll() throws IOException {
// GET book/_search
// {
// "query": {
// "match_all": {}
// }
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//获取某些字段
searchSourceBuilder.fetchSource(new String[]{"name"}, new String[]{});
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" + id);
System.out.println("score:" + score);
System.out.println("name:" + name);
System.out.println("description:" + description);
System.out.println("price:" + price);
System.out.println("==========================");
}
}
}
2.page
@Test
public void testSearchPage() throws IOException {
// GET book/_search
// {
// "query": {
// "match_all": {}
// },
// "from": 0,
// "size": 2
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//第几页
int page = 1;
//每页几个
int size = 2;
//下标计算
int from = (page - 1) * size;
searchSourceBuilder.from(from);
searchSourceBuilder.size(size);
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" + id);
System.out.println("name:" + name);
System.out.println("description:" + description);
System.out.println("price:" + price);
System.out.println("==========================");
}
}
3.ids
@Test
public void testSearchIds() throws IOException {
// GET /book/_search
// {
// "query": {
// "ids" : {
// "values" : ["1", "4", "100"]
// }
// }
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.idsQuery().addIds("1", "4", "100"));
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" + id);
System.out.println("name:" + name);
System.out.println("description:" + description);
System.out.println("price:" + price);
System.out.println("==========================");
}
}
4.match
@Test
public void testSearchMatch() throws IOException {
// GET /book/_search
// {
// "query": {
// "match": {
// "description": "java程序员"
// }
// }
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("description", "java程序员"));
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" + id);
System.out.println("name:" + name);
System.out.println("description:" + description);
System.out.println("price:" + price);
System.out.println("==========================");
}
}
5.term
@Test
public void testSearchTerm() throws IOException {
//
// GET /book/_search
// {
// "query": {
// "term": {
// "description": "java程序员"
// }
// }
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery("description", "java程序员"));
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" + id);
System.out.println("name:" + name);
System.out.println("description:" + description);
System.out.println("price:" + price);
System.out.println("==========================");
}
}
6.multi_match
@Test
public void testSearchMultiMatch() throws IOException {
// GET /book/_search
// {
// "query": {
// "multi_match": {
// "query": "java程序员",
// "fields": ["name", "description"]
// }
// }
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.multiMatchQuery("java程序员", "name", "description"));
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" + id);
System.out.println("name:" + name);
System.out.println("description:" + description);
System.out.println("price:" + price);
System.out.println("==========================");
}
}
7.bool
@Test
public void testSearchBool() throws IOException {
// GET /book/_search
// {
// "query": {
// "bool": {
// "must": [
// {
// "multi_match": {
// "query": "java程序员",
// "fields": ["name","description"]
// }
// }
// ],
// "should": [
// {
// "match": {
// "studymodel": "201001"
// }
// }
// ]
// }
// }
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建multiMatch请求
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("java程序员", "name", "description");
//构建match请求
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("studymodel", "201001");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(multiMatchQueryBuilder);
boolQueryBuilder.should(matchQueryBuilder);
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" + id);
System.out.println("name:" + name);
System.out.println("description:" + description);
System.out.println("price:" + price);
System.out.println("==========================");
}
}
8.filter
@Test
public void testSearchFilter() throws IOException {
// GET /book/_search
// {
// "query": {
// "bool": {
// "must": [
// {
// "multi_match": {
// "query": "java程序员",
// "fields": ["name","description"]
// }
// }
// ],
// "should": [
// {
// "match": {
// "studymodel": "201001"
// }
// }
// ],
// "filter": {
// "range": {
// "price": {
// "gte": 50,
// "lte": 90
// }
// }
//
// }
// }
// }
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建multiMatch请求
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("java程序员", "name", "description");
//构建match请求
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("studymodel", "201001");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(multiMatchQueryBuilder);
boolQueryBuilder.should(matchQueryBuilder);
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(50).lte(90));
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" + id);
System.out.println("name:" + name);
System.out.println("description:" + description);
System.out.println("price:" + price);
System.out.println("==========================");
}
}
9.sort
@Test
public void testSearchSort() throws IOException {
// GET /book/_search
// {
// "query": {
// "bool": {
// "must": [
// {
// "multi_match": {
// "query": "java程序员",
// "fields": ["name","description"]
// }
// }
// ],
// "should": [
// {
// "match": {
// "studymodel": "201001"
// }
// }
// ],
// "filter": {
// "range": {
// "price": {
// "gte": 50,
// "lte": 90
// }
// }
//
// }
// }
// },
// "sort": [
// {
// "price": {
// "order": "asc"
// }
// }
// ]
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建multiMatch请求
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("java程序员", "name", "description");
//构建match请求
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("studymodel", "201001");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(multiMatchQueryBuilder);
boolQueryBuilder.should(matchQueryBuilder);
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(50).lte(90));
searchSourceBuilder.query(boolQueryBuilder);
//按照价格升序
searchSourceBuilder.sort("price", SortOrder.ASC);
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" + id);
System.out.println("name:" + name);
System.out.println("description:" + description);
System.out.println("price:" + price);
System.out.println("==========================");
}
}
4.sql 功能
前提 es 拥有白金版功能:
kibana 中管理-》许可管理 开启白金版试用
导入依赖:
<dependency>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>x-pack-sql-jdbc</artifactId>
<version>7.3.0</version>
</dependency>
<repositories>
<repository>
<id>elastic.co</id>
<url>https://artifacts.elastic.co/maven</url>
</repository>
</repositories>
代码:
public class TestJdbc {
public static void main(String[] args) {
//1创建连接
try {
Connection connection = DriverManager.getConnection("jdbc:es://http://localhost:9200");
//2创建statement
Statement statement = connection.createStatement();
//3执行sql语句
ResultSet resultSet = statement.executeQuery("SELECT * FROM tvs");
//4获取结果
while (resultSet.next()) {
System.out.println(resultSet.getString(1));
System.out.println(resultSet.getString(2));
System.out.println(resultSet.getString(3));
System.out.println(resultSet.getString(4));
System.out.println("======================================");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
5.学成在线站内搜索模块
1.mysql 导入学生数据
/*
Navicat Premium Data Transfer
Source Server : local
Source Server Type : MySQL
Source Server Version : 50721
Source Host : localhost:3306
Source Schema : xc_course
Target Server Type : MySQL
Target Server Version : 50721
File Encoding : 65001
Date: 10/11/2019 02:50:34
*/
SET
NAMES utf8mb4;
SET
FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for course_pub
-- ----------------------------
DROP TABLE IF EXISTS `course_pub`;
CREATE TABLE `course_pub` (
`id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '主键',
`name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '课程名称',
`users` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '适用人群',
`mt` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '大分类',
`st` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '小分类',
`grade` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '课程等级',
`studymodel` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '学习模式',
`teachmode` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '教育模式',
`description` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '课程介绍',
`timestamp` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '时间戳logstash使用',
`charge` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '收费规则,对应数据字典',
`valid` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '有效性,对应数据字典',
`qq` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '咨询qq',
`price` float(10, 2) NULL DEFAULT NULL COMMENT '价格',
`price_old` float(10, 2) NULL DEFAULT NULL COMMENT '原价格',
`expires` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '过期时间',
`start_time` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '课程有效期-开始时间',
`end_time` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '课程有效期-结束时间',
`pic` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '课程图片',
`teachplan` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '课程计划',
`pub_time` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '发布时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of course_pub
-- ----------------------------
INSERT INTO
`course_pub`
VALUES
(
'297e7c7c62b888f00162b8a7dec20000',
'test_java基础33',
'b1',
'1-3',
'1-3-3',
'200002',
'201002',
NULL,
'java 从入门到删库跑路',
'2019-10-28 11:26:25',
'203002',
'204002',
'32432',
NULL,
NULL,
NULL,
NULL,
NULL,
'group1/M00/00/00/wKgZhV2tIgiAaYVMAAA2T52Dthw246.jpg',
'{\"children\":[{\"children\":[],\"id\":\"40288f9b6e0c10d8016e0c37f72a0000\",\"pname\":\"1\"},{\"children\":[{\"id\":\"40288581632b593e01632bd53ff10001\",\"mediaFileoriginalname\":\"solr.avi\",\"mediaId\":\"5fbb79a2016c0eb609ecd0cd3dc48016\",\"pname\":\"Hello World\"},{\"id\":\"40288f9b6e106273016e106485f30000\",\"mediaFileoriginalname\":\"lucene.avi\",\"mediaId\":\"c5c75d70f382e6016d2f506d134eee11\",\"pname\":\"java基础\"}],\"id\":\"40288581632b593e01632bd4ec360000\",\"pname\":\"程序入门\"},{\"children\":[{\"id\":\"40288f9b6dce18e3016dcef16d860001\",\"mediaFileoriginalname\":\"solr.avi\",\"mediaId\":\"5fbb79a2016c0eb609ecd0cd3dc48016\",\"pname\":\"三级节点\"}],\"id\":\"40288f9b6dce18e3016dcef12a1d0000\",\"pname\":\"二级节点\"},{\"children\":[{\"id\":\"40288c9a6ca3968e016ca417fa8d0001\",\"mediaFileoriginalname\":\"lucene.avi\",\"mediaId\":\"c5c75d70f382e6016d2f506d134eee11\",\"pname\":\"test04-01\"}],\"id\":\"40288c9a6ca3968e016ca417b4a50000\",\"pname\":\"test04\"},{\"children\":[{\"id\":\"40288581632b593e01632bd5d31f0003\",\"mediaFileoriginalname\":\"solr.avi\",\"mediaId\":\"5fbb79a2016c0eb609ecd0cd3dc48016\",\"pname\":\"表达式\"},{\"id\":\"40288581632b593e01632bd606480004\",\"pname\":\"逻辑运算\"}],\"id\":\"40288581632b593e01632bd597810002\",\"pname\":\"编程基础\"},{\"children\":[{\"id\":\"402881e764034e4301640351f3d70003\",\"pname\":\"一切皆为对象\"}],\"id\":\"402881e764034e430164035091a00002\",\"pname\":\"面向对象\"},{\"children\":[{\"id\":\"402899816ad8457c016ad9282a330001\",\"pname\":\"test06\"}],\"id\":\"402899816ad8457c016ad927ba540000\",\"pname\":\"test05\"}],\"id\":\"4028858162bec7f30162becad8590000\",\"pname\":\"test_java基础33\"}',
'2019-10-28 11:26:24'
);
INSERT INTO
`course_pub`
VALUES
(
'297e7c7c62b888f00162b8a965510001',
'test_java基础node',
'test_java基础',
'1-3',
'1-3-2',
'200001',
'201001',
NULL,
'test_java基础2test_java基础2test_java基础2test_java基础2test_java基础2test_java基础2test_java基础2test_java基础2test_java基础2test_java基础2',
'2019-10-24 16:26:34',
'203001',
'204001',
'443242',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'{\"children\":[{\"children\":[{\"id\":\"402881e66417407b01641744fc650001\",\"pname\":\"入门程序\"}],\"id\":\"402881e66417407b01641744afc30000\",\"pname\":\"基础知识\"},{\"children\":[],\"id\":\"4028858162e5d6e00162e5e0727d0001\",\"pname\":\"java基础语法\"},{\"children\":[{\"id\":\"4028d0866b158241016b502433d60002\",\"pname\":\"第二节\"}],\"id\":\"4028d0866b158241016b5023f51e0001\",\"pname\":\"第二章\"}],\"id\":\"4028858162e5d6e00162e5e0227b0000\",\"pname\":\"test_java基础2\"}',
'2019-10-24 16:26:33'
);
SET
FOREIGN_KEY_CHECKS = 1;
2.创建索引 xc_course
3.创建映射
PUT /xc_course
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"description" : {
"analyzer" : "ik_max_word",
"search_analyzer": "ik_smart",
"type" : "text"
},
"grade" : {
"type" : "keyword"
},
"id" : {
"type" : "keyword"
},
"mt" : {
"type" : "keyword"
},
"name" : {
"analyzer" : "ik_max_word",
"search_analyzer": "ik_smart",
"type" : "text"
},
"users" : {
"index" : false,
"type" : "text"
},
"charge" : {
"type" : "keyword"
},
"valid" : {
"type" : "keyword"
},
"pic" : {
"index" : false,
"type" : "keyword"
},
"qq" : {
"index" : false,
"type" : "keyword"
},
"price" : {
"type" : "float"
},
"price_old" : {
"type" : "float"
},
"st" : {
"type" : "keyword"
},
"status" : {
"type" : "keyword"
},
"studymodel" : {
"type" : "keyword"
},
"teachmode" : {
"type" : "keyword"
},
"teachplan" : {
"analyzer" : "ik_max_word",
"search_analyzer": "ik_smart",
"type" : "text"
},
"expires" : {
"type" : "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"pub_time" : {
"type" : "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"start_time" : {
"type" : "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"end_time" : {
"type" : "date",
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
}
4.logstash 创建模板文件
Logstash 的工作是从 MySQL 中读取数据,向 ES 中创建索引,这里需要提前创建 mapping 的模板文件以便 logstash 使用。
在 logstach 的 config 目录创建 xc_course_template.json,内容如下:
{
"mappings": {
"doc": {
"properties": {
"charge": {
"type": "keyword"
},
"description": {
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"type": "text"
},
"end_time": {
"format": "yyyy-MM-dd HH:mm:ss",
"type": "date"
},
"expires": {
"format": "yyyy-MM-dd HH:mm:ss",
"type": "date"
},
"grade": {
"type": "keyword"
},
"id": {
"type": "keyword"
},
"mt": {
"type": "keyword"
},
"name": {
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"type": "text"
},
"pic": {
"index": false,
"type": "keyword"
},
"price": {
"type": "float"
},
"price_old": {
"type": "float"
},
"pub_time": {
"format": "yyyy-MM-dd HH:mm:ss",
"type": "date"
},
"qq": {
"index": false,
"type": "keyword"
},
"st": {
"type": "keyword"
},
"start_time": {
"format": "yyyy-MM-dd HH:mm:ss",
"type": "date"
},
"status": {
"type": "keyword"
},
"studymodel": {
"type": "keyword"
},
"teachmode": {
"type": "keyword"
},
"teachplan": {
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"type": "text"
},
"users": {
"index": false,
"type": "text"
},
"valid": {
"type": "keyword"
}
}
}
},
"template": "xc_course"
}
5.logstash 配置 mysql.conf
ES 采用 UTC 时区问题
ES 采用 UTC 时区,比北京时间早 8 小时,所以 ES 读取数据时让最后更新时间加 8 小时
where timestamp > date_add(:sql_last_value,INTERVAL 8 HOUR)
logstash 每个执行完成会在/config/logstash_metadata 记录执行时间下次以此时间为基准进行增量同步数据到索引库。
6.启动
.\logstash.bat -f ..\config\mysql.conf
7.后端代码
代码地址
7.1.Controller
@RestController
@RequestMapping("/search/course")
public class EsCourseController {
@Autowired
private EsCourseServiceImpl esCourseServiceImpl;
@GetMapping(value = "/list/{page}/{size}")
public QueryResponseResult<CoursePub> list(@PathVariable("page") int page
, @PathVariable("size") int size, CourseSearchParam courseSearchParam) {
return esCourseServiceImpl.list(page, size, courseSearchParam);
}
}
7.2.service
@Service
public class EsCourseServiceImpl implements EsCourseService {
@Value("${kwan.course.source_field}")
private String source_field;
@Autowired
private RestHighLevelClient restHighLevelClient;
/**
* 课程搜索
*
* @param page
* @param size
* @param courseSearchParam
* @return
*/
@Override
public QueryResponseResult<CoursePub> list(int page, int size, CourseSearchParam courseSearchParam) {
if (courseSearchParam == null) {
courseSearchParam = new CourseSearchParam();
}
//1创建搜索请求对象
SearchRequest searchRequest = new SearchRequest("xc_course");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//过虑源字段
String[] source_field_array = source_field.split(",");
searchSourceBuilder.fetchSource(source_field_array, new String[]{});
//创建布尔查询对象
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//搜索条件
//根据关键字搜索
if (StringUtils.isNotEmpty(courseSearchParam.getKeyword())) {
MultiMatchQueryBuilder multiMatchQueryBuilder =
QueryBuilders
.multiMatchQuery(courseSearchParam.getKeyword(), "name", "description", "teachplan")
.minimumShouldMatch("70%")
.field("name", 10);
boolQueryBuilder.must(multiMatchQueryBuilder);
}
if (StringUtils.isNotEmpty(courseSearchParam.getMt())) {
//根据一级分类
boolQueryBuilder.filter(QueryBuilders.termQuery("mt", courseSearchParam.getMt()));
}
if (StringUtils.isNotEmpty(courseSearchParam.getSt())) {
//根据二级分类
boolQueryBuilder.filter(QueryBuilders.termQuery("st", courseSearchParam.getSt()));
}
if (StringUtils.isNotEmpty(courseSearchParam.getGrade())) {
//根据难度等级
boolQueryBuilder.filter(QueryBuilders.termQuery("grade", courseSearchParam.getGrade()));
}
//设置boolQueryBuilder到searchSourceBuilder
searchSourceBuilder.query(boolQueryBuilder);
//设置分页参数
if (page <= 0) {
page = 1;
}
if (size <= 0) {
size = 12;
}
//起始记录下标
int from = (page - 1) * size;
searchSourceBuilder.from(from);
searchSourceBuilder.size(size);
//设置高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<font class='eslight'>");
highlightBuilder.postTags("</font>");
//设置高亮字段
highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
searchSourceBuilder.highlighter(highlightBuilder);
searchRequest.source(searchSourceBuilder);
QueryResult<CoursePub> queryResult = new QueryResult();
List<CoursePub> list = new ArrayList<>();
try {
//2执行搜索
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//3获取响应结果
SearchHits hits = searchResponse.getHits();
long totalHits = hits.getTotalHits().value;
//匹配的总记录数
queryResult.setTotal(totalHits);
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
CoursePub coursePub = new CoursePub();
//源文档
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
//取出id
String id = (String) sourceAsMap.get("id");
coursePub.setId(id);
//取出name
String name = (String) sourceAsMap.get("name");
//取出高亮字段name
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
if (highlightFields != null) {
HighlightField highlightFieldName = highlightFields.get("name");
if (highlightFieldName != null) {
Text[] fragments = highlightFieldName.fragments();
StringBuffer stringBuffer = new StringBuffer();
for (Text text : fragments) {
stringBuffer.append(text);
}
name = stringBuffer.toString();
}
}
coursePub.setName(name);
//图片
String pic = (String) sourceAsMap.get("pic");
coursePub.setPic(pic);
//价格
Double price = null;
try {
if (sourceAsMap.get("price") != null) {
price = (Double) sourceAsMap.get("price");
}
} catch (Exception e) {
e.printStackTrace();
}
coursePub.setPrice(price);
//旧价格
Double price_old = null;
try {
if (sourceAsMap.get("price_old") != null) {
price_old = (Double) sourceAsMap.get("price_old");
}
} catch (Exception e) {
e.printStackTrace();
}
coursePub.setPrice_old(price_old);
//将coursePub对象放入list
list.add(coursePub);
}
} catch (IOException e) {
e.printStackTrace();
}
queryResult.setList(list);
QueryResponseResult<CoursePub> queryResponseResult = new QueryResponseResult<>(CommonCode.SUCCESS, queryResult);
return queryResponseResult;
}
}
觉得有用的话点个赞
👍🏻
呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙