Java牛客项目课_仿牛客网讨论区_第六章

Posted 夜中听雪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java牛客项目课_仿牛客网讨论区_第六章相关的知识,希望对你有一定的参考价值。

第六章、Elasticsearch,分布式搜索引擎(9200端口:HTTP、9300端口:TCP)

项目课用的6.4.3的ElasticSearch,我下载的7.12.0(最新版)的ElasticSearch,这两个版本的es在结合SpringBoot时,API有些不一样,就用了个demo来测试下,demo用的用7.12.0的es。
SpringBoot整合ElasticSearch7.12实现增删改查及高亮分词查询_夜中听雪的博客-CSDN博客

6.1、Elasticsearch入门

Elasticsearch术语 :索引(indices)、类型、文档、字段,
在es6.0以前分别对应数据库中的:数据库、表、行、列。

es6.0以后废弃了"类型"这个概念,于是es的索引、文档、字段,
分别对应数据库中的:表、行、列。

多台es服务器合在一起,叫做集群。集群中的一台服务器,叫做节点。集群式部署提高性能。
分片(shard):把一个索引(即一张表),拆分成多个分片去存。提高并发能力。
副本:是对分片的备份,一个分片可以包含多个副本。提高可用性。

命令行使用es:
在这里插入图片描述
实验上图的第一个命令(上图老师把es的bin目录配入了环境变量,所以可以在任何地方访问es的命令。我没配,所以要在es的bin目录下,执行es的命令):

F:\\狂神说ElasticSearch软件\\elasticsearch-7.12.0-windows-x86_64\\elasticsearch-7.12.0\\bin>curl -X GET "localhost:9200/_cat/health?v"
epoch      timestamp cluster       status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1618316206 12:16:46  elasticsearch yellow          1         1     13  13    0    0        6             0                  -                 68.4%

F:\\狂神说ElasticSearch软件\\elasticsearch-7.12.0-windows-x86_64\\elasticsearch-7.12.0\\bin>curl -X GET "localhost:9200/_cat/nodes?v"
ip        heap.percent ram.percent cpu load_1m load_5m load_15m node.role   master name
127.0.0.1           30          63  17                          cdfhilmrstw *      DESKTOP-4OG2TJ0

F:\\狂神说ElasticSearch软件\\elasticsearch-7.12.0-windows-x86_64\\elasticsearch-7.12.0\\bin>curl -X GET "localhost:9200/_cat/indices?v"
health status index                           uuid                   pri rep docs.count docs.deleted store.size pri.store.size

牛客课程助教:
关于ES配置的重要提示
ES在启动时,默认申请1g内存,在学习阶段,这太耗内存了,可以调小一点。大家可以修改其config目录下的jvm.options文件,将初识内存调整为256m,将最大内存调整为512m,如下图:
在这里插入图片描述

6.4、Spring整合Elasticsearch

我用的es版本:

	<properties>
		<java.version>1.8</java.version>
		<elasticsearch.version>7.12.0</elasticsearch.version>
	</properties>
	
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
	</dependency>
import com.nowcoder.community.entity.DiscussPost;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;

/*
ElasticsearchRepository<DiscussPost, Integer>
DiscussPost:接口要处理的实体类
Integer:实体类中的主键是什么类型
ElasticsearchRepository:父接口,其中已经事先定义好了对es服务器访问的增删改查各种方法。Spring会给它自动做一个实现,我们直接去调就可以了。
 */
@Repository
public interface DiscussPostRepository extends ElasticsearchRepository<DiscussPost, Integer> {

}

报错:

NoNodeAvailableException[None of the configured nodes are available: [{#transport#-1}{2VV2VNaCR92yVTgSiExOXA}{127.0.0.1}{127.0.0.1:9300}]]

解决:
1、F:\\狂神说ElasticSearch软件\\elasticsearch-7.12.0-windows-x86_64\\elasticsearch-7.12.0\\config\\elasticsearch.yml,把cluster.name: my-application的注释去掉,然后在idea里springboot项目的application.properties里写spring.data.elasticsearch.cluster-name=my-application。
2、spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300。这里端口是9300,不是9200。

报错:

Error creating bean with name 'searchController': Unsatisfied dependency expressed through field 'elasticsearchService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'elasticsearchService': Unsatisfied dependency expressed through field 'discussRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'discussPostRepository': Invocation of init method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.elasticsearch.repository.support.NumberKeyedRepository]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/elasticsearch/action/admin/indices/mapping/put/PutMappingResponse

解决:
没试过:elasticSearch availableProcessors is already set to [8], rejecting [8]_衫凉℃的博客-CSDN博客

我直接把pom.xml中spring-boot-starter-parent的版本从2.1.5.RELEASE变为2.4.4。

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.4.4</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

然后两个类无法用了,一个类不赞成使用了:

import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.query.SearchQuery;

org.springframework.data.elasticsearch.core @Deprecated 
public class ElasticsearchTemplate

然后用狂神说ElasticSearch7.x的京东搜索项目中的代码重构了。

6.6、开发社区搜索功能

	//get请求的参数不能用请求体来传,只能用search?keyword=xxx或者search/xxx这两种方式来传参
    @RequestMapping(path = "/search", method = RequestMethod.GET)
    public String search(String keyword, Page page, Model model) {

下方,前者是我们自己封装的分页类Page,页码从1开始。后者是es的Page类,页码从0开始。

/**
 * 封装分页相关的信息.
 */
public class Page {

    // 当前页码
    private int current = 1;//从1开始
    public Page<DiscussPost> searchDiscussPost(String keyword, int current, int limit) {//current是当前页,current从0开始
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.multiMatchQuery(keyword, "title", "content"))
                .withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC))
                .withSort(SortBuilders.fieldSort("score").order(SortOrder.DESC))
                .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
                .withPageable(PageRequest.of(current, limit))

注意:这里开始把项目的6.x的es改为7.x的es

pom.xml文件,spring-boot-starter-parent是4.4,导入2.1.4版本的mybatis后报错。

Failed to read artifact descriptor for org.springframework.boot:spring-boot-starter-jdbc:jar:2.4.4
Failure to transfer org.springframework.boot:spring-boot-starter-jdbc:pom:2.4.4 from http://maven.aliyun.com/nexus/conte。。。。。。

这两个错的解决方法都是:
1、spring-boot-starter-parent的版本可能和mybatis的版本不兼容,可以把spring-boot-starter-parent的版本降为4.3.
2、因为是从阿里云的镜像下载jar包,如果你用mybatis的最新版本,可能这个包,在阿里云的镜像上还没有,你可以把mybatis的版本降低为2.1.0。

//这样可以搞定带高亮的查询,用的7.12.0的es。
pom.xml

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.kuang</groupId>
    <artifactId>all-pom</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>all-pom</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.12.0</elasticsearch.version>
    </properties>
@Test
    public void SearchGoods() throws Exception{
        SearchRequest searchRequest = new SearchRequest("discusspost");//discusspost是索引名,就是表名

        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.field("content");
        highlightBuilder.requireFieldMatch(false);
        highlightBuilder.preTags("<em>");
        highlightBuilder.postTags("</em>");

        //构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
                .query(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content"))
                .sort(SortBuilders.fieldSort("type").order(SortOrder.DESC))
                .sort(SortBuilders.fieldSort("score").order(SortOrder.DESC))
                .sort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
                .from(0)// 指定从哪条开始查询
                .size(10)// 需要查出的总记录条数
                .highlighter(highlightBuilder);

        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        List<DiscussPost> list = new LinkedList<>();
        for (SearchHit hit : searchResponse.getHits().getHits()) {
            DiscussPost discussPost = JSONObject.parseObject(hit.getSourceAsString(), DiscussPost.class);

            // 处理高亮显示的结果
            HighlightField titleField = hit.getHighlightFields().get("title");
            if (titleField != null) {
                discussPost.setTitle(titleField.getFragments()[0].toString());
            }
            HighlightField contentField = hit.getHighlightFields().get("content");
            if (contentField != null) {
                discussPost.setContent(contentField.getFragments()[0].toString());
            }
            System.out.println(discussPost);
            list.add(discussPost);
        }
    }

错误:
1、在这里插入图片描述
解决:
[ERROR] Error executing Maven. [ERROR] The specified user settings file does not exist:_往昔岁月的博客-CSDN博客

2、

log4j:ERROR Failed to rename [C:\\Users\\Administrator\\Documents\\kafka/logs/server.log] to [C:\\Users\\Administrator\\Documents\\kafka/logs/server.log.2017-09-20-09].

解决:
logging - Set Kafka log directory property in Windows - Stack Overflow
就是把F:\\Kafka\\kafka_2.13-2.7.0\\config\\server.properties文件中的log.dirs=.\\logs\\kafka-logs 改为log.dirs=./logs/kafka-logs,即反斜线改为正斜线。

3、
org.springframework.boot:spring-boot-starter-parent从2.1.5.RELEASE到2.4.3,导致出现错误。

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-04-22 14:43:31,813 ERROR [main] o.s.b.d.LoggingFailureAnalysisReporter [LoggingFailureAnalysisReporter.java:40] 

***************************
APPLICATION FAILED TO START
***************************

Description:

Invalid mapping pattern detected: /**/*.css
^
No more pattern data allowed after {*...} or ** pattern element

Action:

Fix this pattern in your application or switch to the legacy parser implementation with `spring.mvc.pathpattern.matching-strategy=ant_path_matcher`.

解决:
o.s.b.d.LoggingFailureAnalysisReporter。Invalid mapping pattern detected: /**/*.css。No more pattern。。_夜中听雪的博客-CSDN博客

以上是关于Java牛客项目课_仿牛客网讨论区_第六章的主要内容,如果未能解决你的问题,请参考以下文章

Java牛客项目课_仿牛客网讨论区_第二章

Java牛客项目课_仿牛客网讨论区_第八章

Java牛客项目课_仿牛客网讨论区_第八章

Java牛客项目课_仿牛客网讨论区_第七章

Java牛客项目课_仿牛客网讨论区_第五章

Java牛客项目课_仿牛客网讨论区_html页面