lucene搭建及应用。

1 篇文章 0 订阅

去官网下载Lucene随意一个版本,百度很多下载教程:
我这里下载的是最新的版本
下面是几个较为核心的包:

lucene-analyzers-common-7.2.1.jar
lucene-core-7.2.1.jar
lucene-facet-7.2.1.jar
lucene-highlighter-7.2.1.jar
lucene-memory-7.2.1.jar
lucene-queries-7.2.1.jar
lucene-queryparser-7.2.1.jar

本文是基于磁盘索引的创建。

package com.ucap.cmssearch;

import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;

//创建索引
public class CreatIndexs{

     @Test
     public void creatIndexs() throws Exception{
        /*RobotService RobotService =new RobotServiceImpl();*/
        //分词器,例如我们搜索“金刚葫芦娃”,也可以按“金刚”或者“葫芦娃”两个词分别搜索。
        Analyzer luceneAnalyzer = new StandardAnalyzer(); 
        //索引文件存储路径我的在D:\\luceneIndex这个文件下
        Directory dir=FSDirectory.open(Paths.get("D:\\luceneIndex"));  
        //被IndexWriter类依赖的配置类
        IndexWriterConfig iwc=new IndexWriterConfig(luceneAnalyzer);
        //IndexWriter 是 Lucene 用来创建索引的一个核心的类,他的作用是把一个个的 Document 对象加到索引中来。
        IndexWriter indexWriter = new IndexWriter(dir,iwc);
        //Robot实体类
        List<Robot> list = new ArrayList<>();
        Robot a = new Robot();
        a.setId("1");
        a.setAnswer("lucene是最屌的");
        list.add(a);
        Robot b = new Robot();
        b.setId("2");
        b.setAnswer("哈哈哈");
        list.add(b);
        Robot c = new Robot();
        c.setId("3");
        c.setAnswer("lucene是重货的");
        list.add(c); 
        for (Robot aa : list) {
            //DocumentDocument 是用来描述文档的。
            //一个 Document 对象由多个 Field 对象组成的。
            //可以把一个 Document 对象想象成数据库中的一个记录,而每个 Field 对象就是记录一个字段。
            Document doc=new Document();
            //Field.Store.YES属性是否要被存储,索引,YES代表在文档中存储。NO反之。
            doc.add(new StringField("id",aa.getId(), Field.Store.YES));
            doc.add(new TextField("Answer",aa.getAnswer(), Field.Store.YES));
            indexWriter.addDocument(doc); 
            System.out.println(doc.get("Answer"));
            }
            //跟事物的概念一样。
             indexWriter.commit();  
             indexWriter.close();    
        } 

}

运行结果:
以下是lucene生成的索引
这里写图片描述

//索引查询

package com.ljl.lucene.demo.search;
import java.io.IOException;
import java.io.StringReader;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;

import com.ucap.cmssearch.Robot;



public class ReadIndexByDisk {

       private Directory dir;
       private IndexReader reader;
       private IndexSearcher is;
       //准备工作,先获取所以生成的路径,读取。
       public void setUp() throws Exception {
          dir=FSDirectory.open(Paths.get("D:\\luceneIndex"));
          reader=DirectoryReader.open(dir);
          is=new IndexSearcher(reader);
       }
       //结束后关闭
       public void tearDown() throws Exception {
          reader.close();
       }


       //索引查询
       @Test
       public void TermQuery()throws Exception{
           String fileID= "Answer";  //指定Field
           String keyword= "lucene";//查询的关键字

          List<Robot> list = new ArrayList<Robot>(); 
          this.setUp();//预备工作
          Term t=new Term(fileID,keyword);//Term 是搜索的基本单位,跟POJO道理差不多
          Query query=new TermQuery(t);
          TopDocs hits=is.search(query, 10);//查询构造参数的10为查询结果为10条
          System.out.println("*******************"+hits.totalHits+"*******************");
          //文本高亮格式构造参数为关键字的高亮格式
          SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");
          //创建高亮器
          Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
          //依赖分词器
          Analyzer luceneAnalyzer = new StandardAnalyzer(); 
          for(ScoreDoc scoreDoc:hits.scoreDocs){
             Document doc=is.doc(scoreDoc.doc);
             Robot robot = createObj(doc, luceneAnalyzer, highlighter);
             list.add(robot);
          }
          this.tearDown();

       }

       public Robot createObj(Document doc, Analyzer analyzer, Highlighter highlighter) throws IOException, InvalidTokenOffsetsException { 
        Robot robot = new Robot();
        String answer = null2String(doc.get("Answer"));
        if (doc != null) {
            if (!"".equals(answer)) {
                // analyzer.tokenStream()分词器做好处理之后得到的一个流,这个流中存储了分词的各  种信息.可以通过TokenStream有效的获取到分词单元
                TokenStream tk = analyzer.tokenStream("Answer", new StringReader(answer));
                //获取文档片段,从新给实体类赋值。
                String htext = null2String(highlighter.getBestFragment(tk, answer));
                if (!"".equals(htext)) {
                    robot.setAnswer(htext);
                }
            }
        }
        return robot;
        } 

       private static String null2String(String str) {
            if (str == null) {
                return "";
            }
            return str;
        }



}

简单例子开心就好!,想深入学习可以参考官方文档,以及源码。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值