【Elasticsearch系列五】Java API

news/2024/9/19 4:52:40/ 标签: elasticsearch, java, 大数据

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
img

  • 推荐: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
java">@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
java">@Slf4j
@SpringBootTest(classes = SearchApplication.class)
@RunWith(SpringRunner.class)
public class TestDocument_01_get {@AutowiredRestHighLevelClient client;@Testpublic 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("数据不存在");}}
}
java">@Testpublic 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
java">@Testpublic 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);}}}
java"> @Testpublic 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);}}}
java">@Testpublic 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);}}}
java">@Testpublic 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);}}}
java">@Testpublic 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
java">@Testpublic 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
java">@Testpublic 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
java">@Testpublic 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.创建索引
java">@SpringBootTest
@RunWith(SpringRunner.class)
public class TestIndex_01_Create {@Autowiredprivate RestHighLevelClient client;//创建索引@Testpublic 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"));//指定映射1createIndexRequest.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);}
}
java">@SpringBootTest
@RunWith(SpringRunner.class)
public class TestIndex_04_Async {@Autowiredprivate RestHighLevelClient client;//创建索引异步方式@Testpublic void testCreateIndexAsync() {//创建索引对象CreateIndexRequest createIndexRequest = new CreateIndexRequest("itheima_book");//设置参数createIndexRequest.settings(Settings.builder().put("number_of_shards", "1").put("number_of_replicas", "0"));//指定映射1createIndexRequest.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>() {@Overridepublic void onResponse(CreateIndexResponse createIndexResponse) {//得到响应(全部)boolean acknowledged = createIndexResponse.isAcknowledged();//得到响应 指示是否在超时前为索引中的每个分片启动了所需数量的碎片副本boolean shardsAcknowledged = createIndexResponse.isShardsAcknowledged();System.out.println("acknowledged:" + acknowledged);System.out.println("shardsAcknowledged:" + shardsAcknowledged);}@Overridepublic void onFailure(Exception e) {e.printStackTrace();}};client.indices().createAsync(createIndexRequest, RequestOptions.DEFAULT, listener);try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}}
}
2.删除索引
java">@Testpublic 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.是否存在索引
java"> @Testpublic 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.关闭索引
java">@Testpublic 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.打开索引
java">@Testpublic 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
java">@SpringBootTest
@RunWith(SpringRunner.class)
public class TestSearch_01_all {@AutowiredRestHighLevelClient client;@Testpublic 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
java">@Testpublic 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
java">@Testpublic 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
java">@Testpublic 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
java">@Testpublic 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
java">@Testpublic 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
java"> @Testpublic 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
java">@Testpublic 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
java">@Testpublic 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>

代码:

java">public class TestJdbc {public static void main(String[] args) {//1创建连接try {Connection connection = DriverManager.getConnection("jdbc:es://http://localhost:9200");//2创建statementStatement 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 TransferSource Server         : localSource Server Type    : MySQLSource Server Version : 50721Source Host           : localhost:3306Source Schema         : xc_courseTarget Server Type    : MySQLTarget Server Version : 50721File Encoding         : 65001Date: 10/11/2019 02:50:34*/
SETNAMES utf8mb4;SETFOREIGN_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');SETFOREIGN_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
java">@RestController
@RequestMapping("/search/course")
public class EsCourseController {@Autowiredprivate 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
java">@Service
public class EsCourseServiceImpl implements EsCourseService {@Value("${kwan.course.source_field}")private String source_field;@Autowiredprivate RestHighLevelClient restHighLevelClient;/*** 课程搜索** @param page* @param size* @param courseSearchParam* @return*/@Overridepublic 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到searchSourceBuildersearchSourceBuilder.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();//取出idString id = (String) sourceAsMap.get("id");coursePub.setId(id);//取出nameString name = (String) sourceAsMap.get("name");//取出高亮字段nameMap<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对象放入listlist.add(coursePub);}} catch (IOException e) {e.printStackTrace();}queryResult.setList(list);QueryResponseResult<CoursePub> queryResponseResult = new QueryResponseResult<>(CommonCode.SUCCESS, queryResult);return queryResponseResult;}
}

觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

img


http://www.ppmy.cn/news/1526254.html

相关文章

C++系列-函数对象/仿函数

函数对象/仿函数 &#x1f4a2;什么是仿函数&#x1f4a2;仿函数的使用&#x1f4a2;&#x1f4a2;像普通函数一样使用&#x1f4a2;&#x1f4a2;可以有自己的状态&#x1f4a2;&#x1f4a2;可以作为函数的参数&#x1f4a2;&#x1f4a2;可以作为模板参数&#x1f4a2;&…

ElementUI 快速入门:使用 Vue 脚手架搭建项目

文章目录 一 . ElementUI 的基本安装1.1 通过 Vue 脚手架创建项目1.2 在 vue 脚手架中安装 ElementUI1.3 编写页面 ElementUI 是 Vue.js 的强大 UI 框架&#xff0c;让前端界面开发变得简单高效。本教程将带你从安装到实战&#xff0c;快速掌握 ElementUI 的核心技巧。 核心内容…

手机玩机常识____展讯芯片刷机平台ResearchDownload的一些基本常识与问题解决

展讯ResearchDownload工具 展讯芯片的刷机工具--ResearchDownload下载工具"是一款专为用户设计的高效、便捷的下载管理软件&#xff0c;它能够帮助用户快速、稳定地从互联网上获取各种文件。这款工具以其强大的功能和良好的用户体验&#xff0c;在众多展讯芯片下载工具中脱…

【大数据方案】智慧大数据平台总体建设方案书(word原件)

第1章 总体说明 1.1 建设背景 1.2 建设目标 1.3 项目建设主要内容 1.4 设计原则 第2章 对项目的理解 2.1 现状分析 2.2 业务需求分析 2.3 功能需求分析 第3章 大数据平台建设方案 3.1 大数据平台总体设计 3.2 大数据平台功能设计 3.3 平台应用 第4章 政策标准保障体系 4.1 政策…

校园水电费管理|基于java的校园水电费管理小程序系统 (源码+数据库+文档)

校园水电费管理 目录 基于java的校园水电费管理小程序系统 一、前言 二、系统设计 三、系统功能设计 小程序端 后台功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕…

Spring Boot-API版本控制问题

在现代软件开发中&#xff0c;API&#xff08;应用程序接口&#xff09;版本控制是一项至关重要的技术。随着应用的不断迭代&#xff0c;API 的改动不可避免&#xff0c;如何在引入新版本的同时保证向后兼容&#xff0c;避免对现有用户的影响&#xff0c;是每个开发者需要考虑的…

掌握MATLAB中的图形用户界面布局管理器

在MATLAB中&#xff0c;图形用户界面&#xff08;GUI&#xff09;的设计对于创建专业且用户友好的应用至关重要。布局管理器在GUI设计中扮演着核心角色&#xff0c;它们负责在窗口中自动管理和调整控件的位置和大小。本文将详细介绍MATLAB中的布局管理器&#xff0c;包括它们的…

[PICO VR眼镜]眼动追踪串流Unity开发与使用方法,眼动追踪打包报错问题解决(Eye Tracking)

前言 最近在做一个工作需要用到PICO4 Enterprise VR头盔里的眼动追踪功能&#xff0c;但是遇到了如下问题&#xff1a; 在Unity里面没法串流调试眼动追踪功能&#xff0c;根本获取不到Device&#xff0c;只能将整个场景build成APK&#xff0c;安装到头盔里&#xff0c;才能在…

Oracle 11gR2打PSU补丁详细教程

1 说明 Oracle的PSU&#xff08;Patch Set Update&#xff09;补丁是Oracle公司为了其数据库产品定期发布的更新包&#xff0c;通常每季度发布一次。PSU包含了该季度内收集的一系列安全更新&#xff08;CPU&#xff1a;Critical Patch Update&#xff09;以及一些重要的错误修…

6芯7芯可旋转电连接器航空插头

概述 可旋转电航空插头是一种能够在旋转或相对运动的部件间稳定传输电气信号或电源的装置&#xff0c;广泛应用于航空航天、自动化设备、医疗设备等多个领域。它的核心在于精密的接触系统&#xff0c;由旋转端和固定端两部分组成&#xff0c;通过金属触点或导电环实现电气连接。…

Unity 粒子系统参数说明

一、Particle System 1. Duration&#xff08;持续时间&#xff09; 粒子系统运行一次所需的时间。它决定粒子系统持续播放的时间长度。 2. Looping&#xff08;循环播放&#xff09; 如果启用&#xff0c;粒子系统将在播放完一次后自动重新开始播放&#xff0c;直到你停止它…

SpringBoot框架Web开发

1. 控制器开发 (1) JSON的支持 Spring Boot默认支持JSON格式的数据交换&#xff0c;主要通过以下方式实现&#xff1a; 依赖&#xff1a;spring-boot-starter-web 依赖包已经包括了 Jackson&#xff0c;用于将Java对象序列化为JSON&#xff0c;以及将JSON反序列化为Java对象…

Protubuf入门

⼀、初识 ProtoBuf 1. 序列化概念 序列化和反序列化 序列化&#xff1a;把对象转换为字节序列的过程 称为对象的序列化。 反序列化&#xff1a;把字节序列恢复为对象的过程 称为对象的反序列化。 什么情况下需要序列化 存储数据&#xff1a;当你想把的内存中的对象状态…

Java零基础-replace(CharSequence target, CharSequence replacement)详解

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云/阿里云/华为云/51CTO&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互…

2024年某大厂HW蓝队面试题分享

&#x1f91f; 基于入门网络安全/黑客打造的资源包无偿分享中&#xff1a; &#x1f449;黑客&网络安全入门&进阶学习资源包 应急响应流程 1&#xff09;首先判断服务器资产、影响范围以及严重程度&#xff0c;确认有没有必要将服务器下线隔离&#xff0c;然后根据服务…

【佳学基因检测】在织梦网站中, 创建或修改目录:/var/www/html/cp 失败! DedeTag Engine Create File False

【佳学基因检测】在织梦网站中, 创建或修改目录&#xff1a;/var/www/html/cp 失败&#xff01; DedeTag Engine Create File False 在使用 DedeCMS&#xff08;一个常用的内容管理系统&#xff09;时&#xff0c;如果遇到“创建或修改目录&#xff1a;/var/www/html/cp 失败&…

工程师 - HUE(Humans in User Experience)介绍

HUE&#xff1a;Humans in User Experience&#xff08;用户体验中的人类&#xff09;是用户体验&#xff08;UX&#xff09;设计领域的一种概念或方法&#xff0c;强调在设计过程中考虑人的因素的重要性。它侧重于了解用户的需求、行为和情感&#xff0c;从而创造出更有效、更…

flask框架

Flask 1 flask简介 我们之所以在浏览器中输入localhost:8080然后就可以把webapps下面的项目文件以浏览器的方式打开&#xff0c;功臣在与tomcat。python语言写的项目&#xff0c;转换为web&#xff0c;Flask框架 轻量级web应用框架。 环境准备&#xff1a; pip install fl…

基于鸿蒙API10的RTSP播放器(七:亮度调节功能测试)

目标&#xff1a; 当我的手指在设备左方进行上下移动的时候&#xff0c;可以进行屏幕亮度的调节&#xff0c;在调节的同时&#xff0c;有实时的调节进度条显示 步骤&#xff1a; 界面逻辑&#xff1a;使用Stack() 组件&#xff0c;完成音量图标和进度条的组合显示&#xff0c…

鹏哥C语言自定义笔记重点(67-)

67. 68. 69. 70. 71.结构体内容 72.理解结构体的字节数 73. #pragma once //头文件中使用&#xff0c;功能是:防止头文件被多次引用 74.结构体传参 结论:结构体传参时&#xff0c;要传结构体地址。 75.位段 76.static是只能在该文件中看到&#xff0c;其他地方看不到 77.…