基于Solr实现全文搜索

背景

学习JAVA快两年,搭建了一个基于SpringBoot的个人博客。有一个需求:通过任意关键字搜索对应博客。
分析:如果直接访问数据库,因为是%like%查询,数据库不会走索引,只会全表扫描,效率过低,通过搜索资料发现。

海量数据,使用mysql或者Oracle进行模糊查询或者条件查询效率低下(当不使用索引)。

搜索解决方案:
(1)基于Apache Lucene实现搜索
(2)基于谷歌API实现搜索
(3)基于百度API实现搜索—(优势在于坐标搜索:地图)

Solr是基于Apache Lucene构建的用于搜索和分析的开源解决方案。专门做全文搜索,是一个高性能,采用Java开发,基于Lucene的全文搜索服务器,本质上是一个JAVA Web项目。

前期准备

(1)下载并安装solr,本文下载版本为solr-7.7.3
(2)数据库mysql,本文版本为mysql-5.7.11-winx64
(3)中文分词器 ,本文版本为ik-analyzer-7.6.0.jar

开始

(1)在D:\Solr\solr-7.7.3\server\solr目录下创建文件search
(2)将D:\Solr\solr-7.7.3\server\solr\configsets_default中conf文件复制到search中
(3)solr服务器添加core
在这里插入图片描述
(4)安装中文分词器

将.jar包放入server\solr-webapp\webapp\WEB-INF\lib即可

(5)修改search文件中managed-schema的配置

<!-- 中文分词器-->
 <field name="zh_all" type="text_zh_all" indexed="true" stored="true"/>
	 <field name="zh_smart" type="text_zh_smart" indexed="true" stored="true"/>
	 	 
	<fieldType name="text_zh_all" class="solr.TextField">
      <analyzer type="index">
        <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory"  useSmart="false" conf="ik.conf"/>
        <filter class="solr.LowerCaseFilterFactory"/> </analyzer>
        <analyzer type="query">
        <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory"  useSmart="false" conf="ik.conf"/>
        <filter class="solr.LowerCaseFilterFactory"/>
	  </analyzer>
	</fieldType>
	<fieldType name="text_zh_smart" class="solr.TextField">
      <analyzer type="index">
        <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory"  useSmart="true" conf="ik.conf"/>
        <filter class="solr.LowerCaseFilterFactory"/> </analyzer>
        <analyzer type="query">
        <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory"  useSmart="true" conf="ik.conf"/>
        <filter class="solr.LowerCaseFilterFactory"/>
	  </analyzer>
	</fieldType>

(6)配置handler
在search中的solrconfig.xml中配置

  <!-- 增加配置-->
   <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
    <lst name="defaults">
      <str name="config">dataimport.xml</str>  
    </lst>
  </requestHandler>

(7)新建dataimport.xml,配置数据库查询

<?xml version="1.0" encoding="UTF-8"?>
<dataConfig>
<dataSource type="JdbcDataSource"
            driver="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/blog"
            user="root"
            password="Root1234/"/>
<document>
<entity name="BlogProduct" query="SELECT id,content from t_search">
<!--  把查询字段的结果写入 索引库对应的字段-->
<field column="id" name="id"/>
<field column="content" name="zh_all"/>
</entity>
</document>
</dataConfig>

(8) 上传相关jar包

  • mysql对应jar包
  • dataimport相关Jar包

位置:solr-7.7.3\server\solr-webapp\webapp\WEB-INF\lib

dataimport相关Jar包在Solr\solr-7.7.3\dist\:两个

(9) 将数据库数据导入并测试
在这里插入图片描述

在这里插入图片描述

(10) springboot中maven配置


```java
<?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.2.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.cqu</groupId>
    <artifactId>newblog</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>newblog</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
            <version>1.9.22</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.38</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.5</version>
        </dependency>
        <!--导入solr-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-solr</artifactId>
            <version>7.7.3</version>
        </dependency>
        <!--参数校验-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-solr</artifactId>
            <version>4.3.9</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.solr</groupId>
            <artifactId>solr-solrj</artifactId>
            <version>8.8.2</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!--<configuration>-->
                <!--<failOnMissingWebXml>false</failOnMissingWebXml>-->
                <configuration>
                    <!-- 程序的主启动类,即:用@SpringBootApplication注解,包含main方法的类 -->
                    <mainClass>com.cqu.newblog.MainApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <!--</configuration>-->
            </plugin>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.7</version>
                <!-- 添加一个mysql的依赖,防止等会找不到driverClass -->
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>5.7.11</version>
                        <scope>runtime</scope>
                    </dependency>
                </dependencies>
                <!-- mybatisGenerator 的配置 -->
                <configuration>
                    <!-- generator 工具配置文件的位置 -->
                    <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
                    <!-- 是否覆盖 -->
                    <!-- 此处要特别注意,如果不加这个设置会导致每次运行都会在原目录再次创建-->
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>
        </plugins>
    </build>

(11)Application.properties配置

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.resources.add-mappings=true
spring.resources.cache.period=P7D
spring.resources.chain.cache=true
spring.resources.chain.enabled=true
spring.resources.chain.compressed=true
spring.resources.chain.html-application-cache=true

(12)实体类

@SolrDocument
@Data
public class BlogVo {
    @Id
    private String id;
    @Field
    private String content;

}

(13)controller搜索功能实现

 @PostMapping("/value")
    public String serachBlog(Model model, @RequestParam("searchValue") String searchValue){

        //搜索内容
        model.addAttribute("searchContent",searchValue);
        //Spring data 通用条件模板
        Criteria c = Criteria.where("zh_all").is(searchValue);
        //查询条件对象
        Query query = Query.query(c);
        //分页
        query.setPageRequest(PageRequest.of(0, 100));
        //spring data 中排序规则
        query.addSort(Sort.by(Sort.Direction.ASC, "id"));


        ScoredPage<BlogVo> page = solrTemplate.queryForPage("search", query, BlogVo.class);

        Float maxScore = page.getMaxScore();

        if (page == null) {
            System.out.println("不存在该关键词");
        }
        List<BlogVo> blogVos = page.getContent();
        Integer searchNum=blogVos.size();
        solrTemplate.commit("search");
        if(searchNum!=null){
            model.addAttribute("searchNum",searchNum);
        }
        List<IndexVo> indexVos=blogService.getIndexVoListByBlogVoList(blogVos);


        if(indexVos!=null){
            model.addAttribute("indexVos", indexVos);
        }

        //联系我
        User user = userService.getUserByUserId(1);
        model.addAttribute("user",user);
        //最新博客
        List<Blog> blogList=blogService.getRecentBlog(3);;
        model.addAttribute("blogList",blogList);
        return "search";


    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值