java——lucene实现全文检索(一)建立索引

需求:对多个文档内的数据进行全文检索(文档包括.txt .doc .docx .pdf)

1.对各个文档建立索引

2.对索引进行搜索

各个依赖:

<!-- lucene 核心模块  -->
<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-core</artifactId>
    <version>7.3.0</version>
</dependency>

<!-- Lucene提供的中文分词器模块,lucene-analyzers-smartcn:Lucene  的中文分词器 SmartChineseAnalyzer -->
<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-analyzers-smartcn</artifactId>
    <version>7.3.0</version>
</dependency>


<!-- ikanalyzer 中文分词器  -->
<dependency>
    <groupId>com.janeluo</groupId>
    <artifactId>ikanalyzer</artifactId>
    <version>2012_u6</version>
    <!--排除掉里面旧的lucene包,因为我们要重写里面的分析器和分词器  -->
    <exclusions>
        <exclusion>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-queryparser</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-analyzers-common</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!--  lucene-queryparser 查询分析器模块 -->
<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-queryparser</artifactId>
    <version>7.3.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-scratchpad -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>3.17</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.17</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox -->
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>1.8.10</version>
</dependency>

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

建立索引:

/***
 * 创建索引
 * @param targetFileDir 源文件夹
 * @param indexSaveDir 索引存放文件夹
 * @throws IOException
 */
public static void indexCreate(File targetFileDir, File indexSaveDir) throws IOException {
    // 不是目录或不存在则返回
    if (!targetFileDir.isDirectory() || !targetFileDir.exists()) {
        return;
    }
    // 保存Lucene索引文件的路径
    Directory directory = FSDirectory.open(indexSaveDir.toPath());
    // 创建一个简单的分词器,可以对数据进行分词
    Analyzer analyzer = new StandardAnalyzer();
    // 创建索引实例
    IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
    IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);
    // 获取所有需要建立索引的文件
    File[] files = targetFileDir.listFiles();
    for (int i = 0; i < files.length; i++) {
        // 文件的完整路径 files[i].toString()
        // 获取文件名称
        String fileName = files[i].getName();
        // 获取文件后缀名,将其作为文件类型
        String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()).toLowerCase();
        Document doc = new Document();
        InputStream in = new FileInputStream(files[i]);

        FieldType fieldType = new FieldType();
        fieldType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
        fieldType.setStored(true);
        fieldType.setTokenized(true);

        if (fileType != null && !fileType.equals("")) {
            if (fileType.equals("doc")) {
                // 获取doc的word文档
                WordExtractor wordExtractor = new WordExtractor(in);
                // 创建Field对象,并放入doc对象中
                doc.add(new Field("contents", wordExtractor.getText(), fieldType));
                // 关闭文档
                wordExtractor.close();
            } else if (fileType.equals("docx")) {
                // 获取docx的word文档
                XWPFWordExtractor xwpfWordExtractor = new XWPFWordExtractor( new XWPFDocument(in));
                // 创建Field对象,并放入doc对象中
                doc.add(new Field("contents", xwpfWordExtractor.getText(), fieldType));
                // 关闭文档
                xwpfWordExtractor.close();
            } else if (fileType.equals("pdf")) {
                // 获取pdf文档
                PDFParser parser = new PDFParser(in);
                parser.parse();
                PDDocument pdDocument = parser.getPDDocument();
                PDFTextStripper stripper = new PDFTextStripper();
                // 创建Field对象,并放入doc对象中
                doc.add(new Field("contents", stripper.getText(pdDocument), fieldType));
                // 关闭文档
                pdDocument.close();
            } else if (fileType.equals("txt")) {
                String txtFile = FileUtils.readFileToString(files[i]);
                // 创建Field对象,并放入doc对象中
                doc.add(new Field("contents", txtFile, fieldType));
            } else {
                System.out.println("文件类型格式错误!!!");
                continue;
            }
        }
        // 创建文件名的域,并放入doc对象中
        doc.add(new Field("filename", files[i].getName(), fieldType));
        // 创建时间的域,并放入doc对象中
        doc.add(new Field("indexDate", DateTools.dateToString(new Date(), DateTools.Resolution.DAY), fieldType));
        // 写入IndexWriter
        indexWriter.addDocument(doc);
    }
    // 查看IndexWriter里面有多少个索引
    System.out.println("查看IndexWriter里面有多少个索引:" + indexWriter.numDocs());
    // 关闭索引
    indexWriter.close();
}

重复生成索引会造成索引重复

先删除掉索引目录下的所有索引

/**
 * 删除指定索引库下面的所有 索引数据
 * @param indexDir
 */
public static void indexDelAll(File indexDir) throws IOException {
    if (indexDir == null || !indexDir.exists() || indexDir.isFile()) {
        return;
    }
    // 创建 IKAnalyzer 中文分词器
    Analyzer analyzer = new IKAnalyzer();
    Directory directory = FSDirectory.open(indexDir.toPath());
    // 创建 索引写配置对象,传入分词器
    IndexWriterConfig config = new IndexWriterConfig(analyzer);
    // 创建 索引写对象
    IndexWriter indexWriter = new IndexWriter(directory, config);
    /** 删除所有索引
     * 如果索引库中的索引已经被删除,则重复删除时无效*/
    indexWriter.deleteAll();
    /** 虽然不 commit,也会生效,但建议做提交操作,*/
    indexWriter.commit();
    /**  关闭流,里面会自动 flush*/
    indexWriter.close();
}

猜你喜欢

转载自blog.csdn.net/yilia_jia/article/details/86627251