SpringBoot+Lucene第四篇 — 入门代码

需求:通过关键字搜索文件,凡是文件名或文件内容包括关键字的文件都需要找出来:下图(是一堆文件列表)

pom.xml

<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-core</artifactId>
    <version>4.10.2</version>
</dependency>
<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-analyzers-common</artifactId>
    <version>4.10.2</version>
</dependency>
<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-queryparser</artifactId>
    <version>4.10.2</version>
</dependency>
<dependency>
    <groupId>com.janeluo</groupId>
    <artifactId>ikanalyzer</artifactId>
    <version>2012_u6</version>
</dependency>

<!--中文分词器-->
<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-analyzers-smartcn</artifactId>
    <version>7.6.0</version>
</dependency>
<!--文件IO操作-->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

代码

import ch.qos.logback.core.net.SyslogOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;

import java.io.File;

public class FileTest {
    /**
     * 创建索引
     * @throws Exception
     */
    @Test
    public void createIndex() throws Exception{
        //索引库存放的位置,也可以放在硬盘
        Directory directory = FSDirectory.open(new File("./index"));
        //标准的分词器
        Analyzer analyzer = new StandardAnalyzer();
        //创建输出流write
        IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_2, analyzer);
        IndexWriter indexWriter = new IndexWriter(directory, config);

        //创建Filed域
        File f = new File("F:\\a");
        //找到下面的所有待搜索的文件
        File[] listFiles = f.listFiles();
        for (File file:listFiles) {
            //创建文档对象
            Document document = new Document();
            //文件名称
            String file_name = file.getName();
            Field fileNameFiled=new TextField("fileName", file_name, Field.Store.YES);
            //文件大小
            long file_size = FileUtils.sizeOf(file);
            Field fileSizeField = new LongField("fileSize", file_size,Field.Store.YES);
            //文件路径
            String file_path = file.getPath();
            Field filePathField = new StoredField("filePath", file_path);
            //文件内容
            String file_content = FileUtils.readFileToString(file, "utf8");
            Field fileContentField = new TextField("fileContent", file_content, Field.Store.YES);

            //保存到文件对象里
            document.add(fileNameFiled);
            document.add(fileSizeField);
            document.add(filePathField);
            document.add(fileContentField);

            //写到索引库
            indexWriter.addDocument(document);
        }
        //关闭
        indexWriter.close();
    }

    /**
     * 查询索引
     * @throws Exception
     */
    @Test
    public void searchIndex() throws Exception{
        //第一步,查询准备工作,创建Directory对象
        Directory dir = FSDirectory.open(new File("./index"));
        //创建IndexReader对象
        IndexReader reader = DirectoryReader.open(dir);
        //创建IndexSearch对象
        IndexSearcher search = new IndexSearcher(reader);

        //第二步,闯将查询条件对象
        TermQuery query = new TermQuery(new Term("fileContent", "what"));
        //第三步:执行查询,参数(1:查询条件对象,2:查询结果返回的最大值)
        TopDocs topDocs = search.search(query, 10);
        //第四步:处理查询结果
        //输出结果数量
        System.out.print("查询结果数量:" + topDocs.totalHits);
        //取得结果集
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc:scoreDocs) {
            System.out.println("当前doc得分:" + scoreDoc.score);
            //根据文档对象ID取得文档对象
            Document doc=search.doc(scoreDoc.doc);
            System.out.println("文件名称:" + doc.get("fileName"));
            System.out.println("文件路径:" + doc.get("filePath"));
            System.out.println("文件大小:" + doc.get("fileSize"));
            System.out.println("=======================================");
        }
        //关闭IndexReader对象
        reader.close();
    }
}

searchIndex()方法运行后出现类似的索引库,则表示成功

searchIndex()执行相应的搜索条件之后:

通过以上的两段代码我们实现了创建索引与查询索引

第一段代码做了这么几个事:

  • 将我们要查询的每个文档,构建了文档对象。文档对象里面存放的就是该文档的信息(文件名,大小,内容,路径等)
  • 将该文档对象扔进索引库(自动创建了索引)
  • 索引库存放在./index目录下

第二段代码:

就是到索引库的目录下,找fileContent里面有whatt的文档,然后输出了该文档的信息

中文分词器:

我们还是面临一个问题:如何通过“全文” 搜到我们想要的“全文检索.txt”文档?

我们通过lukeall查看索引,找到了原因。那就是没有正确的分词,是因为我们在代码中使用的是官方推荐的标准分词器,而这个分词器,是老外的,不能对中文进行分词,所以我们要使用中文分词器。而现在lucene的中文分词器:CJK词器,smartChinese分词器

  • CJK分词器:是二分法:举例:我爱写代码,分成:我爱,爱写,写代,代码
  • smartChinese:扩展性不太好
  • 市场用的有:庖丁解牛,mmseg4j,但是这两个作者多年没有更新了

这里主要介绍IK分词器的使用:

<dependency>
    <groupId>com.janeluo</groupId>
    <artifactId>ikanalyzer</artifactId>
    <version>2012_u6</version>
</dependency>

之前的代码里用的是标准分词器,老外的,不支持中文分词,下面换Ik分词器

//标准的分词器
//Analyzer analyzer = new StandardAnalyzer();
//下面替换为ik分词器
Analyzer analyzer = new IKAnalyzer();

再执行查询方法,可以看到中文查询条件也可以的到结果在这里插入图片描述

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/05/03/springboot-lucene-chapter-4-getting-started-code/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
SpringBoot+Lucene第四篇 — 入门代码
需求:通过关键字搜索文件,凡是文件名或文件内容包括关键字的文件都需要找出来:下图(是一堆文件列表) pom.xml <dependency> <groupId>org……
<<上一篇
下一篇>>
文章目录
关闭
目 录