Lucene实例解析

在介绍lucene之前我们先介绍一下我们常用的数据分类。

1.数据分类
我们生活中的数据总体分为两种:结构化数据和非结构化数据。
结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。
非结构化数据:指不定长或无固定格式的数据,如邮件,word文档等磁盘上的文件

2.非结构化数据的查询方法
(1)顺序扫描法(Serial Scanning)
所谓顺序扫描,比如要找内容包含某一个字符串的文件,就是一个文档一个文档的看,对于每一个文档,从头看到尾,如果此文档包含此字符串,则此文档为我们要找的文件,接着看下一个文件,直到扫描完所有的文件。如利用windows的搜索也可以搜索文件内容,只是相当的慢。
(2)全文检索(Full-text Search)
将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。这部分从非结构化数据中提取出的然后重新组织的信息,我们称之索引
这种先建立索引,再对索引进行搜索的过程就叫全文检索(Full-text Search)。

虽然创建索引的过程也是非常耗时的,但是索引一旦创建就可以多次使用,全文检索主要处理的是查询,所以耗时间创建索引是值得的。

3.全文检索
我们可以使用Lucene实现全文检索。Lucene是apache下的一个开放源代码的全文检索引擎工具包。提供了完整的查询引擎和索引引擎,部分文本分析引擎。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能。

4.lucene执行过程
在这里插入图片描述
lucene创建索引与查询索引的思路

5.具体代码实现
(1)创建索引和查询索引

package com.lucenen.demo;

import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.jupiter.api.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;

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


public class LuceneTest {

    /**
     * 创建索引
     */
    @Test
    public void createIndex() throws IOException {
        //创建索引写对象
        //索引放的位置
        Directory directory = FSDirectory.open(new File("F:\\lucene\\index"));
        //分词器对象
        Analyzer analyzer = new IKAnalyzer();
        IndexWriterConfig config=new IndexWriterConfig(Version.LUCENE_43,analyzer);
        IndexWriter indexWrtite = new IndexWriter(directory,config);
        //读取要查询的文件
        File file=new File("F:\\lucene\\resource");
        File[] files=file.listFiles();
        for(File f:files){
            //创建文件对象
            Document document=new Document();
            String filename=f.getName();
            //创建域对象
            Field filedName=new TextField("filename",filename, Field.Store.YES);
            long size= FileUtils.sizeOf(f);
            Field fileSize=new LongField("fileSize",size, Field.Store.YES);
            String  filePath=f.getPath();
            Field filePaths=new StoredField("filePath",filePath);
            //把域对象添加到文档中
            document.add(filedName);
            document.add(fileSize);
            document.add(filePaths);
            //把文档写到索引中
            indexWrtite.addDocument(document);
        }
        indexWrtite.close();
    }

    /**
     * 搜索索引
     */
    @Test
    public void readerIndex() throws IOException {
        //创建directory对象也就是索引放的位置
        Directory directory=FSDirectory.open(new File("F:\\lucene\\index"));
        //创建查询对象
        IndexReader indexReader=IndexReader.open(directory);
        //创建indexSearcher对象
        IndexSearcher indexSearcher=new IndexSearcher(indexReader);
        //创建查询对象,teremquery
        Query query=new TermQuery(new Term("filename","给力"));
        //Query query=new TermQuery(new Term("fileSize","49"));
        //执行查询
        TopDocs topDocs=indexSearcher.search(query,5);
        //返回查询结果
        ScoreDoc[] scoreDocs=topDocs.scoreDocs;
        for(ScoreDoc scoreDoc:scoreDocs){
            //根据id查询得到document
            int id=scoreDoc.doc;
            Document document=indexSearcher.doc(id);
            System.out.println(document.get("filename"));
            System.out.println(document.get("fileSize"));
            System.out.println(document.get("filePath"));
        }
        indexReader.close();
    }
}

(2)索引维护(增加,删除,修改,查询)

package com.lucenen.demo;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.jupiter.api.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;

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

/**
 * lucene的维护
 * 添加
 * 删除
 * 修改
 * 查询(花式查询)
 */
public class LuceneManger {

    /**
     * 获取IndexWriter对象
     * @return
     * @throws IOException
     */
    public IndexWriter getIndexWriter() throws IOException {
        //索引文件位置
        Directory directory= FSDirectory.open(new File("F:\\lucene\\index"));
        Analyzer analyzer=new IKAnalyzer();
        IndexWriterConfig config=new IndexWriterConfig(Version.LUCENE_43,analyzer);
        //创建Ind
        IndexWriter indexWriter =new IndexWriter(directory,config);
        return indexWriter;
    }

    /**
     * 根据条件删除
     * @throws IOException
     */
    @Test
    public void deleteIndex() throws IOException {
        IndexWriter indexWriter=getIndexWriter();
       // indexWriter.deleteDocuments(new Term("filename","高富帅"));
        indexWriter.deleteAll();
        indexWriter.close();
    }

    /**
     * 修改索引
     * @throws IOException
     */
    @Test
    public void updateIndex() throws IOException {
        IndexWriter indexWriter=getIndexWriter();
        Document document=new Document();
        //创建的新的域
        document.add(new TextField("filename","给力", Field.Store.YES));
        //替换域
        indexWriter.updateDocument(new Term("filename","高富帅"),document,new IKAnalyzer());
        indexWriter.close();
    }

    /**
     * 返回IndexSearcher对象
     * @return
     * @throws IOException
     */
    public IndexSearcher getIndexReader() throws IOException {
        //索引文件位置
        Directory directory=FSDirectory.open(new File("F:\\lucene\\index"));
        //索引读对象
        DirectoryReader indexWriter= DirectoryReader.open(directory);
        return new IndexSearcher(indexWriter);
    }

    /**
     * 打印出查询结果
     * @param indexSearcher
     * @param query
     * @throws IOException
     */
    public void printIndex(IndexSearcher indexSearcher, Query query) throws IOException {
        TopDocs topDocs=indexSearcher.search(query,50);
        ScoreDoc[] scoreDocs=topDocs.scoreDocs;
        for(ScoreDoc scoreDoc:scoreDocs){
            int id=scoreDoc.doc;
            Document document=indexSearcher.doc(id);
            document.get("filename");
            document.get("filePath");
            System.out.println(document.get("filename")+document.get("filePath"));
        }
    }

    /**
     * 查询所有
     * @throws IOException
     */
    @Test
    public void selectIndex() throws IOException {
        IndexSearcher indexSearcher=getIndexReader();
        Query query=new MatchAllDocsQuery();
        printIndex(indexSearcher,query);
        indexSearcher.getIndexReader().close();
    }

    /**
     * 组合查询
     * 组合查询用booleanQuery对象
     * @throws IOException
     */
    @Test
    public void mutiIndex() throws IOException {
        IndexSearcher indexSearcher=getIndexReader();
        BooleanQuery booleanQuery=new BooleanQuery();
        Query query1=new TermQuery(new Term("filename","给力"));
        Query query2=new TermQuery(new Term("filename","白富美"));
        booleanQuery.add(query1, BooleanClause.Occur.MUST);
        booleanQuery.add(query2, BooleanClause.Occur.SHOULD);
        printIndex(indexSearcher,booleanQuery);
        indexSearcher.getIndexReader().close();
    }

    /**
     * 另外一种查询方法通过语法查
     * @throws IOException
     */
    @Test
    public void byQueryParser() throws Exception {
        IndexSearcher indexSearcher=getIndexReader();
        //默认查询的域,设置解析器,也就是ika解析器

        QueryParser queryParser=new QueryParser(Version.LUCENE_43,"filename",new IKAnalyzer());
        //域名:值
        Query query=queryParser.parse("filename:白富美");
        printIndex(indexSearcher,query);
        indexSearcher.getIndexReader().close();
    }

    @Test
    public void mulQueryParse() throws Exception {
       IndexSearcher indexSearcher= getIndexReader();
       String[] fields={"filename","filePath"};
        MultiFieldQueryParser queryParser=new  MultiFieldQueryParser(Version.LUCENE_43,fields,new IKAnalyzer());
       Query query=queryParser.parse("白富美");
       printIndex(indexSearcher,query);
       indexSearcher.getIndexReader().close();

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值