Lucene的使用

在面对文章,或者某件物品的描述的时候,我们总希望可以通过搜索某些个关键字将其检索出来,而我们只使用数据的模糊匹配的时候,结果总是不尽如人意,这时候我们就需要使用lucene来进行检索了。

Lucene

lucene是apache开源的一个全文检索的工具.
lucene进行全文检索的时候,先要建立一块空间存储索引,之后使用分词器对内容进行分词,并且建立对应的索引库(同时建立元数据库),而用户需要检索的时候,只要从索引库中进行检索就好。(所以将内容放入索引库是必须的)

导入jar


<dependency>
    <groupId>org.apache.lucenegroupId>
    <artifactId>lucene-coreartifactId>
    <version>4.4.0version>
dependency>

<dependency>
    <groupId>org.apache.lucenegroupId>
    <artifactId>lucene-analyzers-commonartifactId>
    <version>4.4.0version>
dependency>

<dependency>
    <groupId>org.apache.lucenegroupId>
    <artifactId>lucene-analyzers-smartcnartifactId>
    <version>4.4.0version>
dependency>

<dependency>
    <groupId>org.apache.lucenegroupId>
    <artifactId>lucene-queryparserartifactId>
    <version>4.4.0version>
dependency>

<dependency>
    <groupId>com.janeluogroupId>
    <artifactId>ikanalyzerartifactId>
    <version>2012_u6version>
dependency>

使用智能分词器来建立索引库

@Test
    public void testLucene() throws IOException {
        //确定索引库的位置 异常先上抛处理
        FSDirectory directory = FSDirectory.open(new File("E://lucentest"));
//        创建文档对象(索引对象)
        Document document = new Document();
        Integer id = 1;
        String title = "lucene测试的标题:好开心的标题";
        String content = "lucene测试的内容:今天使用了lucene,此时一个测试的content路过";
        //Field.Store.YES 建立索引,并且存储元数据
        //Field.Store.NO 只有索引,没有元数据,查询的时候可以查询到,但是没有元数据
        document.add(new StringField("id",id.toString(), Field.Store.YES));
        document.add(new TextField("title",title,Field.Store.YES));
        document.add(new TextField("content",content,Field.Store.YES));
        //创建智能分词器
        SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_44);
//        创建索引写出对象  传入版本信息和分词器
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_44,analyzer);
        IndexWriter indexWriter = new IndexWriter(directory,indexWriterConfig);
        //写出
        indexWriter.addDocument(document);
        //提交
        //此时可进行处理 如果异常可以  回滚  indexWriter.rollback();
        indexWriter.commit();
        //关闭资源
        indexWriter.close();
    }

如图所示,已经创建好了索引库
Lucene的使用_第1张图片
根据索引库进行检索

/**
     * 进行多列查询
     * 分词器要和创建索引的时候分词器相同
     */
    @Test
    public void testSearch() throws ParseException, IOException {
        //创建分词器
        SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_44);
        //创建一个关键词对象
        String[] filds = {"id","title","content"};
        MultiFieldQueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_44,filds,analyzer);
        //将搜索的关键字放入Query对象中
        Query query = queryParser.parse("使用");
        //读取索引库中的索引
        FSDirectory directory = FSDirectory.open(new File("E://lucentest"));
        DirectoryReader directoryReader = DirectoryReader.open(directory);

        //创建一个查询对象
        IndexSearcher indexSearcher = new IndexSearcher(directoryReader);
        //通过关键词 得到TopDocs对象   传入Query  和  要返回的结果条数
        TopDocs topDocs = indexSearcher.search(query,10);
        //获取ScoreDoc对象
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (int i = 0; i < scoreDocs.length; i++) {
            ScoreDoc scoreDoc = scoreDocs[i];
            //获取document对象在索引库中的编号
            int doc = scoreDoc.doc;
            //通过编号得到对象  查询出来的其中一条数据
            Document document = indexSearcher.doc(doc);
            String id = document.get("id");
            String title = document.get("title");
            String content = document.get("content");
            System.out.println("id:"+id+"title:"+title+"content:"+content);
        }

查询结果,因为索引库只有一条数据,我们只看效果就好。。
在这里插入图片描述
然后呢Lucene基本使用就是这样了。
使用百度进行搜索的时候.我们会发现我们搜索的关键字在内容里面会进行高亮显示,lucene当然也可以做到了。
在来一波依赖


<dependency>
    <groupId>org.apache.lucenegroupId>
    <artifactId>lucene-highlighterartifactId>
    <version>4.4.0version>
dependency>

接下就是修改我们的检索的代码了
1.定义高亮的显示格式。
2.选择高亮显示的内容(也就是我们的query对象了)
3.创建出我们的高亮对象
4.进行高亮处理

/**
     * 进行多列查询
     * 分词器要和创建索引的时候分词器相同
     */
    @Test
    public void testSearch() throws ParseException, IOException, InvalidTokenOffsetsException {
        //创建分词器
        SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_44);
        //创建一个关键词对象
        String[] filds = {"id","title","content"};
        MultiFieldQueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_44,filds,analyzer);
        //将搜索的关键字放入Query对象中
        Query query = queryParser.parse("使用");

//        1.定义高亮的显示格式。  变成红色 并且加粗
        SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("","");
//        2.选择高亮显示的内容(也就是我们的query对象了)
        QueryScorer queryScorer = new QueryScorer(query);
//        3.创建出我们的高亮对象
        Highlighter highlighter = new Highlighter(formatter,queryScorer);

        //读取索引库中的索引
        FSDirectory directory = FSDirectory.open(new File("E://lucentest"));
        DirectoryReader directoryReader = DirectoryReader.open(directory);

        //创建一个查询对象
        IndexSearcher indexSearcher = new IndexSearcher(directoryReader);
        //通过关键词 得到TopDocs对象   传入Query  和  要返回的结果条数
        TopDocs topDocs = indexSearcher.search(query,10);
        //获取ScoreDoc对象
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (int i = 0; i < scoreDocs.length; i++) {
            ScoreDoc scoreDoc = scoreDocs[i];
            //获取document对象在索引库中的编号
            int doc = scoreDoc.doc;
            //通过编号得到对象  查询出来的其中一条数据
            Document document = indexSearcher.doc(doc);
            String id = document.get("id");
            String title = document.get("title");
            String content = document.get("content");
            //        4.进行高亮处理
            String content1 = highlighter.getBestFragment(analyzer,"content",content);
            System.out.println("id:"+id+"title:"+title+"content:"+content1);
        }
    }

结果
在这里插入图片描述

你可能感兴趣的:(java,web)