Lucene

 

Lucene

分类: 技术资料 开源软件 JAVA   640人阅读  评论(1)  收藏  举报

目录(?)[+]

Lucene是什么?

LuceneApache组织的一个用JAVA实现全文搜索引擎的开源项目。后来有人将Lucene移植到。Net语言。

Lucene是一个信息检索的函数库(Library),利用它你可以为你的应用加上索引和搜索的功能。

Lucene的使用者不需要深入了解有关全文检索的知识,仅仅学会使用库中的一个类,你就为你的应用实现全文检索的功能。

不过千万别以为Lucene是一个象google那样的搜索引擎,Lucene甚至不是一个应用程序,它仅仅是一个工具,一个Library。你也可以把它理解为一个将索引、搜索功能封装的很好的一套简单易用的API。利用这套API你可以做很多有关搜索的事情,而且很方便。      

 

Lucene能做什么?

Lucene可以对任何的数据做索引和搜索。 Lucene不管数据源是什么格式,只要它能被转化为文字的形式,就可以被Lucene所分析利用。也就是说不管是MS word Html pdf还是其他什么形式的文件只要你可以从中抽取出文字形式的内容就可以被Lucene所用。你就可以用Lucene对它们进行索引以及搜索。

 

 

如何使用Lucene

示例介绍

1.为作为输入参数的文件夹下的所有txt类型的文件做索引,做好的索引文件放入index文件夹。

2.然后在索引的基础上对文件进行全文搜索。

1. 建立索引

IndexWriter writer = new IndexWriter("index",new StandardAnalyzer(),true);  

Document doc = new Document(); 

doc.Add(new Field(“city”, ”上海”,Field.Store.YES, Field.Index.TOKENIZED));

doc.Add(new Field(“shopname”,”东北菜”,Field.Store.YES,Field.Index.TOKENIZED));

writer.AddDocument(doc);

doc = new Document(); 

doc.Add(new Field(“city”, ”北京”,Field.Store.YES, Field.Index.TOKENIZED));

doc.Add(new Field(“shopname”,”东北菜菜馆”,Field.Store.YES,Field.Index.TOKENIZED));

writer.AddDocument(doc);

writer.SetUseCompoundFile(true);

writer.Optimize();

writer.Close();

 

2. 对索引进行搜索

IndexSearcher indexSearcher= new IndexSearcher(indexDir);

QueryParser parser = new QueryParser("shopname", new StandardAnalyzer());

Query query = parser.Parse(“东北”);

Hits hits = indexSearcher.Search(query);

Document doc;

For (int i = 0 ; i < hits.length();i++)

{

   doc = hits.Doc(i);

   doc.Get(“shopname”).ToString()

}

 

这样就实现了简单的全文搜索了。

 

 

Lucene的包结构

Lucene源码中共包括7个子包,每个包完成特定的功能:  

Lucene包结构功能表

包名

功能

Lucene.Net.Analysis

语言分析器,主要用于的切词,可以扩展此类以支持多种语言

Lucene.Net.Document

索引存储时的文档结构管理,类似于关系型数据库的表结构

Lucene.Net.Index

索引管理,包括索引建立、删除等

Lucene.Net.QueryParser

查询分析器,实现查询关键词间的运算,如与、或、非等

Lucene.Net.Search

检索管理,根据查询条件,检索得到结果

Lucene.Net.Store

数据存储管理,主要包括一些底层的I/O操作

Lucene.Net.Util

一些公用类

 

建立索引时最重要的几个概念

Document:一个要进行索引的单元,相当于数据库的一行纪录,任何想要被索引的数据,都必须转化为Document对象存放。

FieldDocument中的一个字段,相当于数据库中的Column

IndexWriter:负责将Document写入索引文件。通常情况下,IndexWriter的构造函数包括了以下3个参数:索引存放的路径,分析器和是否重新创建索引。特别注意的一点,当IndexWriter执行完addDocument方法后,一定要记得调用自身的close方法来关闭它。只有在调用了close方法后,索引器才会将存放在内在中的所有内容写入磁盘并关闭输出流。

Analyzer:分析器,主要用于文本分词。常用的有StandardAnalyzer分析器,StopAnalyzer分析器,WhitespaceAnalyzer分析器等。

Directory:索引存放的位置。Lucene提供了两种索引存放的位置,一种是磁盘,一种是内存。一般情况将索引放在磁盘上;相应地Lucene提供了FSDirectoryRAMDirectory两个类。

Segment:段,是Lucene索引文件的最基本的一个单位。Lucene说到底就是不断加入新的Segment,然后按一定的规则算法合并不同的Segment以合成新的Segment

 

Lucene建立索引的过程就是将待索引的对象转化为LuceneDocument对象,使用IndexWriter将其写入Lucene自定义格式的索引文件中。待索引的对象可以来自文件、数据库等任意途径,用户自行编码遍历目录读取文件或者查询数据库表取得ResultSetLuceneAPI只负责和字符串打交道。

 

 

Field对象

Lucene的源代码中,可以看出Field 典型构造函数如下:

Field(String name, String value, Field.Store store, Field.Index index)

其中:

Field.Index有四种属性,分别是:

Field.Index.TOKENIZED:分词索引

Field.Index.UN_TOKENIZED不分词进行索引,如作者名,日期等,不再需要分词。

Field.Index.NO:不进行索引,存放不能被搜索的内容如文档的一些附加属性如文档类型, URL等。

Field.Index.NO_NORMS不分词,建索引.但是Field的值不像通常那样被保存,而是只取一个byte,这样节约存储空间。

Field.Store也有三个属性,分别是:

Field.Store.YES:索引文件本来只存储索引数据此设计将原文内容直接也存储在索引文件中,如文档的标题。

Field.Store.NO:原文不存储在索引文件中,搜索结果命中后,再根据其他附加属性如文件的Path,数据库的主键等,重新连接打开原文,适合原文内容较大的情况。

          Field.Store.COMPRESS 压缩存储。

Lucene的基本原理和代码分析:

其中总体架构和索引文件格式是Lucene 2.9的,索引过程分析是Lucene 3.0的。

鉴于索引文件格式没有太大变化,因而原文没有更新,原理和架构的文章中引用了前辈的一些图,可能属于早期的Lucene,但不影响对原理和架构的理解。

本系列文章尚在撰写之中,将会有分词器,段合并,QueryParser,查询语句与查询对象,搜索过程,打分公式的推导等章节。

提前给大家分享,希望大家批评指正。 

 

Lucene学习总结之一:全文检索的基本原理

http://www.cnblogs.com/forfuture1978/archive/2009/12/14/1623594.html

Lucene学习总结之二:Lucene的总体架构

http://www.cnblogs.com/forfuture1978/archive/2009/12/14/1623596.html 

Lucene学习总结之三:Lucene的索引文件格式(1)

http://www.cnblogs.com/forfuture1978/archive/2009/12/14/1623597.html

Lucene学习总结之三:Lucene的索引文件格式(2)

http://www.cnblogs.com/forfuture1978/archive/2009/12/14/1623599.html

Lucene学习总结之三:Lucene的索引文件格式(3)

http://www.cnblogs.com/forfuture1978/archive/2010/02/02/1661436.html

Lucene学习总结之四:Lucene索引过程分析(1)

http://www.cnblogs.com/forfuture1978/archive/2010/02/02/1661439.html

Lucene学习总结之四:Lucene索引过程分析(2)

http://www.cnblogs.com/forfuture1978/archive/2010/02/02/1661440.html

Lucene学习总结之四:Lucene索引过程分析(3)

http://www.cnblogs.com/forfuture1978/archive/2010/02/02/1661441.html

Lucene学习总结之四:Lucene索引过程分析(4) 

http://www.cnblogs.com/forfuture1978/archive/2010/02/02/1661442.html 






Lucene基本使用介绍 
今天用了下Lucene,发现网上虽然也有不少介绍它的文档,不过很多都偏向介绍概念呀、设计或者是一些更为深入的东西,对于其入门使用的介绍性的文档并不多,就写了这么一篇。



Lucene基本使用介绍

 

本文的目的不在于对Lucene的概念和设计这些进行介绍,仅在于介绍怎么样去使用Lucene来达到自己想要的几种常见的全文检索的需求,如果想深入了解Lucene的话本文不会带给你什么收获的。看完本文后想更深入的了解Lucene请访问:http://lucene.apache.org

 

一.  概述

随着系统信息的越来越多,怎么样从这些信息海洋中捞起自己想要的那一根针就变得非常重要了,全文检索是通常用于解决此类问题的方案,而Lucene则为实现全文检索的工具,任何应用都可通过嵌入它来实现全文检索。

二.  环境搭建

从lucene.apache.org上下载最新版本的lucene.jar,将此jar作为项目的build path,那么在项目中就可以直接使用lucene了。

三.  使用说明

3.1.       基本概念

这里介绍的主要为在使用中经常碰到一些概念,以大家都比较熟悉的数据库来进行类比的讲解,使用Lucene进行全文检索的过程有点类似数据库的这个过程,table---à查询相应的字段或查询条件----à返回相应的记录,首先是IndexWriter,通过它建立相应的索引表,相当于数据库中的table,在构建此索引表时需指定的为该索引表采用何种方式进行构建,也就是说对于其中的记录的字段以什么方式来进行格式的划分,这个在Lucene中称为Analyzer,Lucene提供了几种环境下使用的Analyzer:SimpleAnalyzer、StandardAnalyzer、GermanAnalyzer等,其中StandardAnalyzer是经常使用的,因为它提供了对于中文的支持,在表建好后我们就需要往里面插入用于索引的记录,在Lucene中这个称为Document,有点类似数据库中table的一行记录,记录中的字段的添加方法,在Lucene中称为Field,这个和数据库中基本一样,对于Field Lucene分为可被索引的,可切分的,不可被切分的,不可被索引的几种组合类型,通过这几个元素基本上就可以建立起索引了。在查询时经常碰到的为另外几个概念,首先是Query,Lucene提供了几种经常可以用到的Query:TermQuery、MultiTermQuery、BooleanQuery、WildcardQuery、PhraseQuery、PrefixQuery、PhrasePrefixQuery、FuzzyQuery、RangeQuery、SpanQuery,Query其实也就是指对于需要查询的字段采用什么样的方式进行查询,如模糊查询、语义查询、短语查询、范围查询、组合查询等,还有就是QueryParser,QueryParser可用于创建不同的Query,还有一个MultiFieldQueryParser支持对于多个字段进行同一关键字的查询,IndexSearcher概念指的为需要对何目录下的索引文件进行何种方式的分析的查询,有点象对数据库的哪种索引表进行查询并按一定方式进行记录中字段的分解查询的概念,通过IndexSearcher以及Query即可查询出需要的结果,Lucene返回的为Hits.通过遍历Hits可获取返回的结果的Document,通过Document则可获取Field中的相关信息了。

通过对于上面在建立索引和全文检索的基本概念的介绍希望能让你对Lucene建立一定的了解。

3.2.       全文检索需求的实现

索引建立部分的代码:


private void createIndex(String indexFilePath) throws Exception{

        IndexWriter iwriter=getWriter(indexFilePath);

        Document doc=new Document();

        doc.add(Field.Keyword("name","jerry"));

        doc.add(Field.Text("sender","bluedavy@gmail.com"));

        doc.add(Field.Text("receiver","google@gmail.com"));

        doc.add(Field.Text("title","用于索引的标题"));

        doc.add(Field.UnIndexed("content","不建立索引的内容"));

        Document doc2=new Document();

        doc2.add(Field.Keyword("name","jerry.lin"));

        doc2.add(Field.Text("sender","bluedavy@hotmail.com"));

        doc2.add(Field.Text("receiver","msn@hotmail.com"));

        doc2.add(Field.Text("title","用于索引的第二个标题"));

        doc2.add(Field.Text("content","建立索引的内容"));

        iwriter.addDocument(doc);

        iwriter.addDocument(doc2);

        iwriter.optimize();

        iwriter.close();

    }

    

    private IndexWriter getWriter(String indexFilePath) throws Exception{

        boolean append=true;

        File file=new File(indexFilePath+File.separator+"segments");

        if(file.exists())

            append=false; 

        return new IndexWriter(indexFilePath,analyzer,append);

    }


3.2.1.       对于某字段的关键字的模糊查询


Query query=new WildcardQuery(new Term("sender","*davy*"));

        

        Searcher searcher=new IndexSearcher(indexFilePath);

        Hits hits=searcher.search(query);

        for (int i = 0; i < hits.length(); i++) {

            System.out.println(hits.doc(i).get("name"));

        }


3.2.2.       对于某字段的关键字的语义查询


Query query=QueryParser.parse("索引","title",analyzer);

        

        Searcher searcher=new IndexSearcher(indexFilePath);

        Hits hits=searcher.search(query);

        for (int i = 0; i < hits.length(); i++) {

            System.out.println(hits.doc(i).get("name"));

        }


3.2.3.       对于多字段的关键字的查询


Query query=MultiFieldQueryParser.parse("索引",new String[]{"title","content"},analyzer);

        

        Searcher searcher=new IndexSearcher(indexFilePath);

        Hits hits=searcher.search(query);

        for (int i = 0; i < hits.length(); i++) {

            System.out.println(hits.doc(i).get("name"));

        }


3.2.4.       复合查询(多种查询条件的综合查询)


Query query=MultiFieldQueryParser.parse("索引",new String[]{"title","content"},analyzer);

        Query mquery=new WildcardQuery(new Term("sender","bluedavy*"));

        TermQuery tquery=new TermQuery(new Term("name","jerry"));

        

        BooleanQuery bquery=new BooleanQuery();

        bquery.add(query,true,false);

        bquery.add(mquery,true,false);

        bquery.add(tquery,true,false);

        

        Searcher searcher=new IndexSearcher(indexFilePath);

        Hits hits=searcher.search(bquery);

        for (int i = 0; i < hits.length(); i++) {

            System.out.println(hits.doc(i).get("name"));

        }


四.  总结

相信大家通过上面的说明能知道Lucene的一个基本的使用方法,在全文检索时建议大家先采用语义时的搜索,先搜索出有意义的内容,之后再进行模糊之类的搜索,^_^,这个还是需要根据搜索的需求才能定了,Lucene还提供了很多其他更好用的方法,这个就等待大家在使用的过程中自己去进一步的摸索了,比如对于Lucene本身提供的Query的更熟练的掌握,对于Filter、Sorter的使用,自己扩展实现Analyzer,自己实现Query等等,甚至可以去了解一些关于搜索引擎的技术(切词、索引排序 etc)等等。






 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值