Elasticsearch 7.6.1学习(六)springboot集成es使用,项目实战,学会之后才是es的入门

2021-03-02 14:49:27 浏览数 (1)

创建一个项目

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com</groupId>
    <artifactId>demojd</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demojd</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.6.1</elasticsearch.version>
    </properties>

    <dependencies>


<!--        这个就是解析网页的-->

        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.10.2</version>
        </dependency>

es
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.60</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.60</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

yml里面配置

代码语言:javascript复制
server.port=9090
#关闭页面缓存
spring.thymeleaf.cache=false

引入前端的页面

访问前端页面的controller层

代码语言:javascript复制
@Controller
public class IndexCintroller {
    @RequestMapping("/index")
    public String index(){
        return "index";
    }
}

启动项目

以上就是静态的页面

爬虫爬取数据,保存在es里面

导入依赖

代码语言:javascript复制
<!--        这个就是解析网页的-->
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.10.2</version>
        </dependency>

创建实体类

代码语言:javascript复制
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Content {

    private String name;
    private String img;
    private String price;
}

以上的实体类就是存放 爬取下的数据

工具类

这个工具类就是解析网站

业务代码的书写

将爬取下的数据放到es里面

controller层书写

代码语言:javascript复制
    @Autowired
    private ContentService contentService;
//    将爬取的数据保存在es里面的代码
    @RequestMapping("/parse/{keyword}")
    public Boolean parse(@PathVariable("keyword") String keyword) throws IOException {
        return contentService.parseConent(keyword);

    }

service 书写

代码语言:javascript复制
//    将爬取下来的数据放到es里面
    public Boolean parseConent(String keywords ) throws IOException {
		
根据关键字查询数据
        List<Content> contents = new HtmlParseUtil().parseID(keywords);
//        批量将list数据插入到索引库里面

        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("10s");

        // 批处理请求        
        for (int i = 0; i < contents.size(); i  ) {
            // 批量更新和批量删除,就在这里修改对应的请求就可以了  
            bulkRequest.add(
                    new IndexRequest("jd").id(""   (i   1))
                            .source(JSON.toJSONString(contents.get(i)),
                                    XContentType.JSON));
        }
        BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println(bulkResponse.hasFailures());
        // 是否失败,返回 false 代表 成功!
        return !bulkResponse.hasFailures();
    }

访问链接

以上返回true ,意思是 已经将爬下来的数据放到es里面了。我们看看

以上是已经创建的索引

以上是爬取的数据,只是没有将图片爬取下来,这个有待解决

将es里面的数据取出来给前段的接口

controller

代码语言:javascript复制
//    将es里面的数据取出来给前段的接口
    @RequestMapping("/search/{keyword}/{pageNo}/{pageSize}")
    public List<Map<String,Object>> search(@PathVariable("keyword") String keyword,
                                           @PathVariable("pageNo")int pageNo,@PathVariable("pageSize")int pageSize) throws IOException {

        return  contentService.searchPage(keyword,pageNo,pageSize);
    }

service

就是从es数据库里面获取数据返回给前段就可以了,就是一个根据关键字查询

代码语言:javascript复制
  //实现从es里面获取高亮
    public List<Map<String,Object>> searchPage(String keyword,int pageNo,int pageSize) throws IOException {
        if (pageNo<=1){
            pageNo=1;
        }

从哪个索引,也就是哪个数据库查询数据
        SearchRequest searchRequest = new SearchRequest("jd");
        // 构建搜索条件        
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//        高亮  ,以哪个字段里面构建高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
//        不需要多有的都高亮
        highlightBuilder.requireFieldMatch(false);
        highlightBuilder.preTags("<span  style='color:red'>");
        highlightBuilder.postTags("</span>");
将高亮的条件放到   搜索条件对象里面

        sourceBuilder.highlighter(highlightBuilder);
//        分页查询
        sourceBuilder.from(pageNo);
        sourceBuilder.size(pageSize);





        // 查询条件,我们可以使用 QueryBuilders 工具来实现
        // QueryBuilders.termQuery 精确
        //QueryBuilders.matchAllQuery() 匹配所有        
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", keyword);
        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        
        将精确查询的对象放到   搜索对象里面
        sourceBuilder.query(termQueryBuilder);

添加延迟时间
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

放到数据库对象里面
        searchRequest.source(sourceBuilder);

执行
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//        System.out.println(JSON.toJSONString(searchResponse.getHits()));
//        System.out.println("=================================");

//        解析搜索出来的数据,变为前端的格式,
        ArrayList<Map<String,Object>> list = new ArrayList<>();
        for(SearchHit documentFields :searchResponse.getHits().getHits()){
//            解析高亮的字段
            Map<String, HighlightField> highlightFields = documentFields.getHighlightFields();
            HighlightField title = highlightFields.get("name");
//            得到原来的字段
            Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();
            if(title !=null){
                Text[] fragments = title.fragments();  得到高亮字段的值
                String n_title = "";
                for (Text text:fragments){
                    n_title =text;
                }
                sourceAsMap.put("name",n_title);//替换原来的字段

            }


            list.add(sourceAsMap);
        }
        return list;


    }

解释查询es的service的代码

我们要根据关键字查询es数据库。并且要在显示的时候,要将我们查询的关键字高亮显示。这个咋实现呢?

在查询的时候,我们要设置高亮的代码

代码语言:javascript复制
//        高亮  ,以哪个字段里面构建高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
//        不需要多有的都高亮
        highlightBuilder.requireFieldMatch(false);
        highlightBuilder.preTags("<span  style='color:red'>");
        highlightBuilder.postTags("</span>");
将高亮的条件放到   搜索条件对象里面

        sourceBuilder.highlighter(highlightBuilder);

并且这个高亮的字段 和 后面查询的字段名字要一样。 查询语句是

代码语言:javascript复制
 SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

查询的条件是:

代码语言:javascript复制
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", keyword);

最后查询的结果searchResponse是一个集合,我们需要遍历

代码语言:javascript复制
 for(SearchHit documentFields :searchResponse.getHits().getHits()){

            System.out.println(documentFields);

输出的每一个documentFields是

以上和在kibana里面查询出的数据是一样的,因为在查询之前我们设置了高亮字段,并且设置了查询的条件,所以现在我们看到的每一个的结果中

根据查询的关键字中,已经将高亮的字段值中,将关键字用前端代码标注了,也就是已经高亮了。

既然已经查询出的数据已经高亮了,那么从这个结果里面将数据拿出来,整合为前端要的格式返回给前段就可以了。

将高亮里面name的字段放到原来数据里面,替换了,之后返回给前段的name字段里面就是显示高亮了。

关键的一点就是 替换

0 人点赞