美文网首页
lucene的增删改查

lucene的增删改查

作者: 刘书生 | 来源:发表于2019-03-26 16:44 被阅读0次

lucene全文检索,还是直接看代码吧

lucene依赖

<!--lucene核心及其依赖-->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
            <version>7.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-queryparser</artifactId>
            <version>7.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-analyzers-common</artifactId>
            <version>7.6.0</version>
        </dependency>
        <!--中文分词器-->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-analyzers-smartcn</artifactId>
            <version>7.6.0</version>
        </dependency>

IndexReader与IndeaSearch工厂类
新版里面都是用 DirectoryReader 生成IndexReader呢,这里跟老版本很不一样,网上很多都说的是lucene老版本

package cn.wgd.zmx.utils;

import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;

import java.io.File;
import java.io.IOException;

/**
 * 用于维护IndexReader和IndexSearch
 */
public class LuceneFactory {

    private static DirectoryReader indexReader = null;

    private static IndexSearcher indexSearcher = null;

    public static DirectoryReader getIndexReader(IndexWriter indexWriter) {
        synchronized (Object.class) {
            if (indexReader == null) {
                synchronized (Object.class) {
                    if (indexReader == null) {
                        try {
                            indexReader = DirectoryReader.open(indexWriter);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }else{
                        try {
                            DirectoryReader reader = DirectoryReader.openIfChanged(indexReader);
                            indexReader.close();
                            indexReader = reader;
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        return indexReader;
    }

    public static IndexSearcher getIndexSearch(IndexWriter indexWriter) {
        synchronized (Object.class) {
            if (indexSearcher == null) {
                synchronized (Object.class) {
                    if (indexSearcher == null) {
                        DirectoryReader indexReader = LuceneFactory.getIndexReader(indexWriter);
                        indexSearcher = new IndexSearcher(indexReader);
                    }else{
                        try {
                            DirectoryReader directoryReader = DirectoryReader.openIfChanged(LuceneFactory.getIndexReader(indexWriter));
                            indexSearcher = new IndexSearcher(directoryReader);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        return indexSearcher;
    }
}

官网上有说到,DirectoryReader.open(indexWriter);创建IndexReader更快,并且IndexReader每次创建的话,开销非常大,所以上面使用了单例模式,并且如果IndexReader发生变化的时候,我们不直接创建,使用官网推荐的方法DirectoryReader.openIfChanged,先判断变化没,如果变化,我们就在旧的基础上创建IndexReader,然后再通过IndexReader创建IndexSearch开销会比较小。

package cn.wgd.zmx.utils;

import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.ParseException;
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 java.io.IOException;
import java.nio.file.Paths;

/**
 * lucene工具类
 * 可优化的地方:先将索引写入到内存,再批量写入到文件
 */
public class LuceneUtils {

    private static final String INDEX_PATH = "indexDir/";

    /**
     * 索引存放得位置,设置再当前目录下
     */
    private static Directory directory;

    static {
        try {
            directory = FSDirectory.open(Paths.get(INDEX_PATH));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 中文分词器
     */
    private static SmartChineseAnalyzer smartChineseAnalyzer = new SmartChineseAnalyzer();

    /**
     * 创建索引写入配置
     */
    private static IndexWriterConfig indexWriterConfig = new IndexWriterConfig(smartChineseAnalyzer);

    /**
     * 创建索引写入对象
     */
    private static IndexWriter indexWriter;

    static {
        try {
            indexWriter = new IndexWriter(directory, indexWriterConfig);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将indexReader维护成单例
     */
    private static DirectoryReader indexReader = null;

    /**
     * 将indexSearch也维护成单例的
     */
    private static IndexSearcher indexSearch = LuceneFactory.getIndexSearch(indexWriter);

    // 存放到内存中
    // Directory directory = new RAMDirectory();

    public LuceneUtils(){
    }

    /**
     * 增加索引
     */
    public static void addIndex(Document doc) throws IOException {

        /**
         * 通过设置IndexWrite的参数优化索引建立
         */

        //将对象保存到索引库中
        indexWriter.addDocument(doc);

        /**
         * 提交索引
         */
        indexWriter.commit();

        /**
         * 索引关闭
         */
        indexWriter.close();
    }

    /**
     * 查询索引
     */
    public static String findIndex(Term term, Integer n, String field) throws IOException, ParseException {

        TermQuery termQuery = new TermQuery(term);

        TopDocs search = indexSearch.search(termQuery, n);

        ScoreDoc[] scoDoc = search.scoreDocs;

        if (scoDoc == null || scoDoc.length == 0) {
            System.out.println("索引不存在!");
        }
        String s = "";

        for (int i = 0; i < scoDoc.length; i++) {
            Document doc = indexSearch.doc(scoDoc[i].doc);
            s += doc.getField(field);
        }

        return s;
    }

    /**
     * 删除索引
     */
    public static void delIndex(Term term) throws IOException {

        TermQuery termQuery = new TermQuery(term);

        indexWriter.deleteDocuments(termQuery);

        indexWriter.close();

    }

    /**
     * 更新索引
     */
    public static void updateIndex(Term query, Document doc) throws IOException {

        indexWriter.updateDocument(query, doc);

        indexWriter.commit();

        indexWriter.close();
    }

    /**
     * 清空回收站,强制优化
     */
    public static void forceDelete(){
        try {
            indexWriter.forceMergeDeletes();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(indexWriter!=null){
                try {
                    indexWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 用于流的关闭
     */

}

上面带有注释

接下来看下测试,将IndexReader维护成单例和没有维护成单例的时候


image.png image.png

从上面可以很明显的看出,第一次因为需要创建索引,速度差不多,但是从后面读的次数很明显可以看出,速度有提升。

需要测试代码的私信我,不想在文章里面贴的太长,影响阅读

相关文章

  • lucene的增删改查

    lucene全文检索,还是直接看代码吧 lucene依赖 IndexReader与IndeaSearch工厂类新版...

  • 搜索学习入门--使用LuceneHighlighter高亮显示L

    在上一篇文章搜索学习入门--Lucene初体验(Lucene索引的增删改查)的基础上,我们进行对Lucene检索结...

  • mysql的插入语句

    MySQL增删改查之增insert、replace

  • MYSQL数据库的增删改查

    MYSQL数据库的增删改查 一.对于库的增删改查 增create database 库名称;create data...

  • 关于python的list的增查删改

    说到增查删改,想起了数据库,我们在关系型数据库当中就会对表进行增查删改。 在python当中我们也可以对list进...

  • 0812 A

    mongodb 增删改查 增: db.createCollection("name", {options:numb...

  • 增删改

    对于表中的操作,就是增删改查,查内容较多,这里先说增删改。 1.增(insert或者load) 即插入数据,多行插...

  • Lucene入门1:索引的增、查

    因工作需要接触Lucene,今天简单对Lucene索引的增删改查有了一个初步了解。先用起来,再逐步根据需要深入了解...

  • SQL查询结构总结

    SQL 增删改查 对数据库有修改的操作是:增删改 增 insert into 表名 values(); 删 del...

  • 2018-03-03

    rails c增删改查 增:user = User.create(name:'Jack', age:'18') 删...

网友评论

      本文标题:lucene的增删改查

      本文链接:https://www.haomeiwen.com/subject/biknvqtx.html