全文检索技术lucene的demo

lucene是一个基于Java的全文检索库,使用lucene能够创建全文索引和搜索,当数据量比较大的时候,比起传统的顺序搜索,索引搜索速度提升会非常明显。很多搜索引擎例如Elasticsearch 和 solor 都是以lucene为核心的。

全文检索

全文检索指的是,提前对文章或者文档中的每一个词建立索引,索引中包含该词在文章中出现的位置和次数,当用户查询时,根据事先建立好的索引进行查找,并返回查询结果。

这种建立索引,在通过搜索索引返回数据的方式就叫全文检索。

优点:

  • 查询准确高。
  • 查询速度快,不会随着数据量的增大而变得越来越慢。

缺点:

  • 索引会占据磁盘存储空间

应用场景:

  • 大量数据检索(贴吧,论坛,淘宝,京东)
  • 搜索引擎 (google、baidu)

Lucene

Lucene是Apache旗下的一个开源全文检索引擎库,提供了完整了查询引擎和索引引擎。使用lucene可以在系统中实现全文检索功能,或者以此为基础构建一个全文检索引擎。
Lucene不是现成的搜索引擎产品,但确可以用来制作搜索引擎产品。

Lucene实现全文检索的流程

假如要为数据库中的数据库建立全文检索,大致的步骤如下:先获取到数据库中的数据库,对这批数据创建索引,索引存储在索引库中。当用户查询时,对索引库的索引进行查找,从而找到相对应的数据。

重点在于创建索引的这部分。创建索引时需要将数据构建为Lucene中的 文档对象,并对文档对象进行分析,最后创建索引

代码步骤如下:

1.创建索引:

  • 获取数据
  • 创建Document文档对象()
  • 创建分词器
  • 创建Directory对象,声明索引库存储位置
  • 创建IndexWriterConfig配置信息类
  • 创建IndexWriter写入对象
  • 把Document写入到索引库中(底层自动创建索引)
  • 关闭写入流

POJO类省略–

Dao层省略–

pom.xml 中引入依赖:

<!--lucene核心-->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
            <version>7.7.2</version>
        </dependency>
        <!--lucene分词器-->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-analyzers-common</artifactId>
            <version>7.7.2</version>
        </dependency>
        <!--lucene查询解析-->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-queryparser</artifactId>
            <version>7.7.2</version>
        </dependency>
        <!--中文分词器-->
        <dependency>
            <groupId>org.wltea.ik-analyzer</groupId>
            <artifactId>ik-analyzer</artifactId>
            <version>8.1.0</version>
        </dependency>

测试类
创建索引:

/*### 
创建索引:
*   获取数据
*   创建Document文档对象()
*   创建分词器
*   创建Directory对象,声明索引库存储位置
*   创建IndexWriterConfig配置信息类
*   创建IndexWriter写入对象
*   把Document写入到索引库中(底层自动创建索引)
*/
//创建全部索引
    @Test
    public void createIndex() throws IOException {


        //获取原始数据
        List<YxStoreProduct> skuList = yxStoreProductRepository.findAll();
        //创建分词器
        Analyzer analyzerIK = new IKAnalyzer();
        //创建文档对象集合
        List<Document> documents =new ArrayList<>();
        for (YxStoreProduct sku : skuList) {
            Document document = new Document();
            document.add(new StringField("id",sku.getId().toString(), Field.Store.YES));
            document.add(new TextField("store_name",sku.getStoreName(), Field.Store.YES));
            document.add(new TextField("storeInfo",sku.getStoreInfo(), Field.Store.YES));
            document.add(new TextField("price",sku.getPrice().toString(), Field.Store.YES));
            documents.add(document);
        }
        Directory directory = FSDirectory.open(Paths.get("D:\\lucene\\indexDir"));
        Directory directory2 = FSDirectory.open(Paths.get(msgIndex));


        //创建IndexWriterConfig对象,写入索引需要的配置
        IndexWriterConfig config = new IndexWriterConfig(analyzerIK);
        //创建IndexWriter写入对象
        IndexWriter indexWriter = new IndexWriter(directory2,config);
        indexWriter.addDocuments(documents);
        indexWriter.close();
    }

搜索索引:

@Test
    public void searchIndex() throws Exception {
        //创建分词器
        Analyzer analyzerIK = new IKAnalyzer();
        //创建Directory流对象,声明索引库位置
        Directory directory = FSDirectory.open(Paths.get("D:\\yshop\\msgindex"));
        //创建搜索解析器 第一个参数是指定默认搜索的field
        QueryParser queryParser = new QueryParser("store_name",analyzerIK);
        //创建搜索对象 
        Query query = queryParser.parse("商品");
        //创建索引读取对象
        IndexReader reader = DirectoryReader.open(directory);
        //创建索引搜索对象
        IndexSearcher searcher = new IndexSearcher(reader);


        //使用索引搜索对象执行搜索
        TopDocs topDocs =searcher.search(query,10);
        System.out.println("查询到的数据总条数是:"+topDocs.totalHits);
        //获取查询结果集
        ScoreDoc[] docs = topDocs.scoreDocs;


        //解析结果集:
        for(ScoreDoc scoreDoc:docs){
            //拿到文档id
            int docID = scoreDoc.doc;
            Document doc =searcher.doc(docID);


            System.out.println("=============================");
            System.out.println("docID:"+docID);
            System.out.println("id:"+doc.get("id"));
            System.out.println("store_name:"+doc.get("store_name"));
            System.out.println("storeInfo:"+doc.get("storeInfo"));
            System.out.println("price:"+doc.get("price"));
        }
        reader.close();
    }

结果展示:

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!