全文检索课程

Lucene&Solr(1)

  

 

 

1.   计划

率先龙:Lucene的基础知识

1、案例解析:什么是全文检索,如何实现全文检索

2、Lucene实现全文检索的流水线

a)       创建索引

b)       查询索引

3、配置出条件

4、创建索引库

5、查询索引库

6、分析器的分析过程

a)       测试分析器的分词效果

b)       第三在中文分析器

7、索引库的护卫

a)       添加文档

b)       删除文档

c)        修改文档

8、Lucene的高等级查询Lucene的询问

a)       使用Query的子类查询

  1. MatchAllDocsQuery
  2. TermQuery
  3. NumericRangeQuery
  4. BooleanQuery

b)       使用QueryParser

  1. QueryParser
  2. MulitFieldQueryParser

 

 

2.   案例

落实一个文本之索功能,通过主要字搜索文件,凡是文件称或文件内容连要字的公文都用寻找出来。还好依据中文词语进行查询,并且用支持多只规范查询。

该案例被之初内容就是磁盘上之文书,如下图:

 

 

jQuery 1

 

 

3.   需求分析

3.1. 数据库搜索

数据库被的寻怪易实现,通常都是运sql语句进行询问,而且能够充分快之收获查询结果。

怎么数据库搜索怪易?

因数据库中之数据存储是发出规律的,有执行有列又数量格式、数据长度还是稳的。

 

3.2. 数据分类

俺们活着之多少完全分为两种:结构化数据及无结构化数据。

结构化数据:指有固定格式或鲜长度的数,如数据库,元数据等。

未结构化数据:指不定长还是凭固定格式的数额,如邮件,word文档等磁盘上之文本

 

3.3. 非结构化数据查询艺术

(1)顺序扫描法(Serial Scanning)

所谓顺序扫描,比如要摸内容包含有一个字符串的文书,就是一个文档一个文档的看,对于每一个文档,从头看到尾,如果这个文档包含此字符串,则是文档为咱设摸的文本,接着看下一个文书,直到扫描了所有的公文。如运用windows的查找也得以找寻文件内容,只是相当的放缓。

(2)全文检索(Full-text Search)

拿无结构化数据被之同一有信息提取出,重新组织,使其易得起一定结构,然后针对斯有得结构的数据开展查找,从而达成搜索相对比快的目的。这有些自无结构化数据遭到领取出底下一场还组织的信息,我们称之索引

比如:字典。字典的拼音表和部首检字表就一定给字典的目,对各一个许的诠释是不结构化的,如果字典没有音节表和部首检字表,在开阔辞海中摸索一个许只能挨个扫描。然而字的少数信息可领出来进行结构化处理,比如读音,就较结构化,分声母和韵母,分别只有出几种好一一列举,于是将读音拿出去按一定之顺序排列,每一样桩读音都因为者字之事无巨细说明的页数。我们寻找时本结构化的拼音搜到读音,然后照该对的页数,便只是找到我们的不结构化数据——也就是针对许的解说。

这种先成立目录,再针对索引进行搜索的过程就是让全文检索(Full-text
Search)。

尽管创立索引的历程也是可怜耗时的,但是索引一旦创立就可以频繁应用,全文检索主要处理的凡查询,所以耗时间开立索引是值得的。

3.4. 如何促成全文检索

好用Lucene实现全文检索。Lucene是apache下的一个放源代码的全文检索引擎工具包。提供了整机的询问引擎和索引引擎,部分文件分析引起擎。Lucene的目的是啊软件开发人员提供一个简单好用之家伙确保,以造福的当靶体系被实现全文检索的作用。

 

3.5. 全文检索的施用场景

于数据量大、数据结构不固定的数据可采取全文检索方式搜索,比如百度、Google等搜寻引擎、论坛站内搜索、电商网站站内搜索等。

 

4.   Lucene实现全文检索的流水线

4.1. 索引暨找流程图

 jQuery 2

 

 

1、绿色代表索引过程,对要摸索的原本内容展开索引构建一个索引库,索引过程包括:

规定原始内容就如摸的情à采集文档à创建文档à分析文档à索引文档

        

2、红色表示找过程,从索引库中觅内容,搜索过程包括:

用户通过搜索界面à创建查询à执行搜,从索引库搜索à渲染搜索结果

 

4.2. 创立索引

本着文档索引的历程,将用户要摸的文档内容开展索引,索引存储在索引库(index)中。

这边我们若找的文档是磁盘上的文书文件,根据案例描述:凡是文件称或文件内容囊括要字之公文都使找出来,这里要针对文本称与文书内容创建索引。

 

4.2.1.    获得原始文档

原有文档是借助要索引和找的情。原始内容包括互联网及之网页、数据库中之数额、磁盘上的文件等。

该案例被的原始内容就是磁盘上之文件,如下图:

 jQuery 3

 

 

 

于互联网上、数据库、文件系统中等获取需要寻找的固有信息,这个进程就是是信征集,信息征集的目的是以对原内容开展索引。

每当Internet上收集信息之软件通常称为爬虫或蜘蛛,也称之为网络机器人,爬虫访问互联网上的各个一个网页,将赢得到之网页内容存储起来。

        
Lucene不提供信息搜集的类库,需要好编写一个爬虫程序实现信息收集,也可以透过有开源软件实现信息搜集,如下:

         Nutch(http://lucene.apache.org/nutch),
Nutch是apache的一个子项目,包括大爬虫工具,能够抓取和辨认web网站数据。

         jsoup(http://jsoup.org/ ),jsoup 是一款Java
的HTML解析器,可一直解析某个URL地址、HTML文本内容。它提供了一样效好刻苦的API,可由此DOM,CSS以及近似于jQuery的操作方法来取出和操作数据。

        
heritrix(http://sourceforge.net/projects/archive-crawler/files/),Heritrix
是一个出于 java
开发的、开源之大网爬虫,用户可使用它来打网上抓取想要之资源。其极美的远在当让其可以的而是扩展性,方便用户实现和谐的抓取逻辑。

该案例我们若抱磁盘上文件的内容,可以通过文件流来读取文本文件的情,对于pdf、doc、xls等公事可经第三正值提供的分析工具读取文件内容,比如Apache
POI读取doc和xls的文书内容。

 

4.2.2.    创建文档对象

获取旧内容之目的是为了索引,在目录前待将故内容创建成文档(Document),文档中连一个一个的域(Field),域中贮存内容。

此我们可将磁盘上的一个文件正是一个document,Document中概括有Field(file_name文件名称、file_path文件路径、file_size文件大小、file_content文件内容),如下图:

 

 jQuery 4

 

 

专注:每个Document可以起差不多个Field,不同的Document可以有差的Field,同一个Document可以来相同的Field(域名与域值都一样)

 

每个文档都生一个唯一的号,就是文档id。

 

4.2.3.    分析文档

用原始内容创建为保含域(Field)的文档(document),需要重对域中之始末开展解析,分析的过程是通过对原来文档提取单词、将字母转为小写、去除标点符号、去除停用词等经过生成最终之词汇单元,可以以语汇单元理解也一个一个之单词。

 

遵下面的文档经过分析如下:

原先文档内容:

Lucene is a Java full-text search engine.  Lucene is not a complete

application, but rather a code library and API that can easily be used

to add search capabilities to applications.

 

分析后取得的词汇单元:

lucene、java、full、search、engine。。。。

 

每个单词叫做一个Term,不同的域中拆分出来的同之单词是见仁见智之term。term中寓两片段片段是文档的域名,另一样部分是才词的情节。

譬如:文件称遭富含apache和文书内容遭涵盖的apache是不同的term。

4.2.4.    创建索引

对持有文档分析得出的词汇单元进行索引,索引的目的是为探寻,最终使兑现只找于索引的词汇单元从而找到Document(文档)。

 
 

 jQuery 5

 

 

留神:创建索引是对准语汇单元索引,通过词语找文档,这种索引的布局给倒排索引结构

风艺术是冲文件找到该公文之始末,在文书内容中匹配搜索关键字,这种措施是各个扫描方法,数据量大、搜索慢。

倒排索引结构举凡根据内容(词语)找文档,如下图:

 jQuery 6

 

 

倒排索引结构吧被反向索引结构,包括索引和文档两局部,索引即词汇表,它的面比小,而文档集合较充分。

 

4.3. 查询索引

查询索引为是找的进程。搜索就用户输入关键字,从目录(index)中开展查找的历程。根据重点字搜索索引,根据目录找到相应之文档,从而找到要寻找的内容(这里因磁盘上之文书)。

 

4.3.1.    用户查询接口

全文检索系统提供用户搜索的界面供用户提交搜索的显要字,搜索就展示搜索结果。

 

比如:

 jQuery 7

 

 

Lucene不提供制作用户搜索界面的职能,需要依据自己的要求开发搜索界面。

4.3.2.    创建查询

用户输入查询关键字执行搜之前要事先构建一个询问对象,查询对象中得指定询问而找的Field文档域、查询关键字当,查询对象见面变动具体的询问语法,

例如:

语法 “fileName:lucene”表示若搜索Field域的情节吧“lucene”的文档

 

4.3.3.    执行查询

搜索索引过程:

据悉查询语法在倒排索引词典表中分头找有相应搜索词的目,从而找到索引所链接的文档链表。

以寻找语法为“fileName:lucene”表示找出fileName域中隐含Lucene的文档。

搜寻过程尽管是于目录上查找域为fileName,并且要字为Lucene的term,并依据term找到文档id列表。

jQuery 8

 

 

4.3.4.    渲染结果

 

因一个祥和的界面将查询结果显示让用户,用户因查找结果招来好想使的音,为了帮忙用户迅速找到好的结果,提供了无数显得的功力,比如寻找结果负以着重字高亮显示,百度提供的快照等。

 

 jQuery 9

 

 

5.   配置出环境

5.1. Lucene下载

Lucene是支付全文检索功能的工具确保,从官方网站下载Lucene4.10.3,并解压。

官方网站:http://lucene.apache.org/

版本:lucene4.10.3

Jdk要求:1.7以上

IDE:Eclipse

 

5.2. 使用的jar包

 

 

Lucene包:

lucene-core-4.10.3.jar

lucene-analyzers-common-4.10.3.jar

lucene-queryparser-4.10.3.jar

 

其它:

commons-io-2.4.jar

junit-4.9.jar

 

6.   功能雷同:创建索引库

采取indexwriter对象创建索引

6.1. 贯彻步骤

先是步:创建一个java工程,并导入jar包。

次步:创建一个indexwriter对象。

1)指定索引库的寄放位置Directory对象

2)指定一个分析器,对文档内容展开辨析。

第二步:创建document对象。

第三步:创建field对象,将field添加到document对象中。

季步:使用indexwriter对象将document对象写入索引库,此过程进行索引创建。并以引得和document对象写入索引库。

第五步:关闭IndexWriter对象。

6.2. Field域的性能

是否分析:是否对域的情节开展分词处理。前提是咱们要对域的情展开查询。

是否索引:将Field分析后底歌词要任何Field值进行索引,只有索引方可搜索到。

照:商品名称、商品简介分析后进行索引,订单号、身份证号不用分析但也要是索引,这些将来还如作为查询条件。

是否存储:将Field值存储于文档中,存储于文档中的Field才堪起Document中得到

遵:商品名称、订单号,凡是将来而自Document中赢得之Field都如存储。

 

是否存储的标准:是否如拿内容显示给用户

 

Field类

数据类型

Analyzed

是否分析

Indexed

是否索引

Stored

是否存储

说明

StringField(FieldName, FieldValue,Store.YES))

字符串

N

Y

Y或N

这个Field用来构建一个字符串Field,但是不会进行分析,会将整个串存储在索引中,比如(订单号,姓名等)

是否存储在文档中用Store.YES或Store.NO决定

LongField(FieldName, FieldValue,Store.YES)

Long型

Y

Y

Y或N

这个Field用来构建一个Long数字型Field,进行分析和索引,比如(价格)

是否存储在文档中用Store.YES或Store.NO决定

StoredField(FieldName, FieldValue)

重载方法,支持多种类型

N

N

Y

这个Field用来构建不同类型Field

不分析,不索引,但要Field存储在文档中

TextField(FieldName, FieldValue, Store.NO)

TextField(FieldName, reader)

 

字符串

Y

Y

Y或N

如果是一个Reader, lucene猜测内容比较多,会采用Unstored的策略.

 

6.3. 代码实现

//创建索引

     @Test

     public void createIndex() throws Exception {

         

          //指定索引库存放的路径

          //D:\temp\0108\index

          Directory directory = FSDirectory.open(new File("D:\\temp\\0108\\index"));

          //索引库还可以存放到内存中

          //Directory directory = new RAMDirectory();

          //创建一个标准分析器

          Analyzer analyzer = new StandardAnalyzer();

          //创建indexwriterCofig对象

          //第一个参数: Lucene的版本信息,可以选择对应的lucene版本也可以使用LATEST

          //第二根参数:分析器对象

          IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);

          //创建indexwriter对象

          IndexWriter indexWriter = new IndexWriter(directory, config);

          //原始文档的路径D:\传智播客\01.课程\04.lucene\01.参考资料\searchsource

          File dir = new File("D:\\传智播客\\01.课程\\04.lucene\\01.参考资料\\searchsource");

          for (File f : dir.listFiles()) {

               //文件名

               String fileName = f.getName();

               //文件内容

               String fileContent = FileUtils.readFileToString(f);

               //文件路径

               String filePath = f.getPath();

               //文件的大小

               long fileSize  = FileUtils.sizeOf(f);

               //创建文件名域

               //第一个参数:域的名称

               //第二个参数:域的内容

               //第三个参数:是否存储

               Field fileNameField = new TextField("filename", fileName, Store.YES);

               //文件内容域

               Field fileContentField = new TextField("content", fileContent, Store.YES);

               //文件路径域(不分析、不索引、只存储)

               Field filePathField = new StoredField("path", filePath);

               //文件大小域

               Field fileSizeField = new LongField("size", fileSize, Store.YES);

              

               //创建document对象

               Document document = new Document();

               document.add(fileNameField);

               document.add(fileContentField);

               document.add(filePathField);

               document.add(fileSizeField);

               //创建索引,并写入索引库

               indexWriter.addDocument(document);

          }

          //关闭indexwriter

          indexWriter.close();

     }

 

6.4. 采用Luke工具查看索引文件

 jQuery 10

 

 

7.   功能二:查询索引

7.1. 贯彻步骤

先是步:创建一个Directory对象,也就算是索引库存放的岗位。

第二步:创建一个indexReader对象,需要指定Directory对象。

老三步:创建一个indexsearcher对象,需要指定IndexReader对象

季步:创建一个TermQuery对象,指定询问的地方和查询的重大词。

第五步:执行查询。

第六步:返回查询结果。遍历查询结果连出口。

第七步:关闭IndexReader对象

7.2. IndexSearcher搜索术

 

方法

说明

indexSearcher.search(query, n)

根据Query搜索,返回评分最高的n条记录

indexSearcher.search(query, filter, n)

根据Query搜索,添加过滤策略,返回评分最高的n条记录

indexSearcher.search(query, n, sort)

根据Query搜索,添加排序策略,返回评分最高的n条记录

indexSearcher.search(booleanQuery, filter, n, sort)

根据Query搜索,添加过滤策略,添加排序策略,返回评分最高的n条记录

 

7.3. 代码实现

//查询索引库

     @Test

     public void searchIndex() throws Exception {

          //指定索引库存放的路径

          //D:\temp\0108\index

          Directory directory = FSDirectory.open(new File("D:\\temp\\0108\\index"));

          //创建indexReader对象

          IndexReader indexReader = DirectoryReader.open(directory);

          //创建indexsearcher对象

          IndexSearcher indexSearcher = new IndexSearcher(indexReader);

          //创建查询

          Query query = new TermQuery(new Term("filename", "apache"));

          //执行查询

          //第一个参数是查询对象,第二个参数是查询结果返回的最大值

          TopDocs topDocs = indexSearcher.search(query, 10);

          //查询结果的总条数

          System.out.println("查询结果的总条数:"+ topDocs.totalHits);

          //遍历查询结果

          //topDocs.scoreDocs存储了document对象的id

          for (ScoreDoc scoreDoc : topDocs.scoreDocs) {

               //scoreDoc.doc属性就是document对象的id

               //根据document的id找到document对象

               Document document = indexSearcher.doc(scoreDoc.doc);

               System.out.println(document.get("filename"));

               //System.out.println(document.get("content"));

               System.out.println(document.get("path"));

               System.out.println(document.get("size"));

          }

          //关闭indexreader对象

          indexReader.close();

     }

7.4. TopDocs

 

Lucene搜索结果而经TopDocs遍历,TopDocs类提供了少量底特性,如下:

 

方法或属性

说明

totalHits

匹配搜索条件的总记录数

scoreDocs

顶部匹配记录

 

注意:

Search方法要指定匹配记录数据n:indexSearcher.search(query, n)

TopDocs.totalHits:是相当配索引库中颇具记录的数额

TopDocs.scoreDocs:匹配相关度高的前头记录数组,scoreDocs的长短小于等于search方法指定的参数n

 

8.   功能三:支持中文分词

8.1. 分析器(Analyzer)的行进程

正如图是语汇单元的浮动过程:

 

 jQuery 11

 

 

起一个Reader字符流开始,创建一个冲Reader的Tokenizer分词器,经过三单TokenFilter生成语汇单元Tokens。

若果扣分析器的解析效益,只待看Tokenstream中的内容即好了。每个分析器都发出一个术tokenStream,返回一个tokenStream对象。

 

8.2. 分析器的分词效果

//查看标准分析器的分词效果

     public void testTokenStream() throws Exception {

          //创建一个标准分析器对象

          Analyzer analyzer = new StandardAnalyzer();

          //获得tokenStream对象

          //第一个参数:域名,可以随便给一个

          //第二个参数:要分析的文本内容

          TokenStream tokenStream = analyzer.tokenStream("test", "The Spring Framework provides a comprehensive programming and configuration model.");

          //添加一个引用,可以获得每个关键词

          CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);

          //添加一个偏移量的引用,记录了关键词的开始位置以及结束位置

          OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);

          //将指针调整到列表的头部

          tokenStream.reset();

          //遍历关键词列表,通过incrementToken方法判断列表是否结束

          while(tokenStream.incrementToken()) {

               //关键词的起始位置

               System.out.println("start->" + offsetAttribute.startOffset());

               //取关键词

               System.out.println(charTermAttribute);

               //结束位置

               System.out.println("end->" + offsetAttribute.endOffset());

          }

          tokenStream.close();

     }

 

8.3. 汉语分析器

8.3.1.    Lucene自带中文分词器

l  StandardAnalyzer:

特字分词:就是依照中文一个字一个字地进行分词。如:“我容易中华”,
效果:“我”、“爱”、“中”、“国”。

l  CJKAnalyzer

亚分割法分词:按两单字展开切分。如:“我是礼仪之邦总人口”,效果:“我是”、“是丁”、“中国”“国人”。

 

上两单分词器无法满足需求。

l  SmartChineseAnalyzer

对汉语支持比较好,但扩大性差,扩展词库,禁用词库和同一词库等不好处理

8.3.2.    第三正中文分析器

  • paoding:
    庖丁解牛最新版本在 https://code.google.com/p/paoding/ 中不过多支持Lucene
    3.0,且行提交的代码在
    2008-06-03,在svn中时髦为是2010年交,已经过时,不予考虑。
  • mmseg4j:最新版本就起 https://code.google.com/p/mmseg4j/ 移至 https://github.com/chenlb/mmseg4j-solr,支持Lucene
    4.10,且当github中流行提交代码是2014年6月,从09年~14年合计发:18个本子,也尽管是同样年几有3只大大小小版本,有较充分的龙腾虎跃度,用了mmseg算法。
  • IK-analyzer:
    最新版本以https://code.google.com/p/ik-analyzer/上,支持Lucene
    4.10自2006年12月推出1.0本开始,
    IKAnalyzer已经生产了4个要命版。最初,它是为开源项目Luence为利用中心的,结合词典分词和文法分析算法的国语分词组件。从3.0版本开
    始,IK发展吗面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。在2012版中,IK实现了简易的分词
    歧义排除算法,标志在IK分词器从仅的词典分词向模拟语义分词衍化。
    但是啊即是2012年12月晚尚未在更新。
  • ansj_seg:最新版本在 https://github.com/NLPchina/ansj_seg tags仅来1.1版,从2012年及2014年创新了大大小小6破,但是笔者本人在2014年10月10日征:“可能本身后来从未生气来维护ansj_seg了”,现在由”nlp_china”管理。2014年11月出创新。并未证实是不是支持Lucene,是一个是因为CRF(条件仍机场)算法所举行的分词算法。
  • imdict-chinese-analyzer:最新版本以 https://code.google.com/p/imdict-chinese-analyzer/ ,
    最新更新也以2009年5月,下载源码,不支持Lucene 4.10
    。是下HMM(隐马尔科夫链)算法。
  • Jcseg:最新版本在git.oschina.net/lionsoul/jcseg,支持Lucene
    4.10,作者有于高的活跃度。利用mmseg算法。

8.3.3.    IKAnalyzer

 jQuery 12

 

运用办法:

率先步:把jar包添加到工程被

亚步:把部署文件和扩充词典和停用词词典添加至classpath下

 

注意:mydict.dic和ext_stopword.dic文件之格式为UTF-8,注意是无BOM 的UTF-8 编码。

 mydict.dic内容是好定义扩展的乐章汇来分词:

高富帅
白富美
二维表


 ext_stopword.dic内容是自己禁止词汇来分词:

我
是
用
二
维
表
来
的
a
an
and
are
as
at
be
but
by
for
if
in
into
is
it
no
not
of
on
or
such
that
the
their
then
there
these
they
this
to
was
will
with

应用EditPlus.exe保存也无BOM 的UTF-8 编码格式,如下图:

 jQuery 13

 

8.4. Analyzer应用时

8.4.1.    索引时使用Analyzer

        
输入关键字展开搜寻,当用为该要字与文档域内容所蕴藏的歌词进行匹配时用对文档域内容进行剖析,需要经过Analyzer分析器处理生成语汇单元(Token)。分析器分析的靶子是文档中的Field域。当Field的性质tokenized(是否分词)为true时会指向Field值进行剖析,如下图:

 jQuery 14

 

 

对此部分Field可以无用分析:

1、不作查询条件的情,比如文件路径

2、不是相当内容中的歌词要匹配Field的总体内容,比如订单号、身份证号等。

 

 

8.4.2.    搜索时用Analyzer

        
对寻找关键字展开解析以及目录分析一样,使用Analyzer对寻找关键字展开辨析、分词处理,使用分析后每个词语进行搜索。比如:搜索关键字:spring
web ,经过分析器进行分词,得出:spring  web拿词去寻找引词典表查找
,找到索引链接到Document,解析Document内容。

        
对于匹配完Field域的查询好于检索时无分析,比如根据订单号、身份证号查询等。

 

         专注:搜索采用的分析器要和目录使用的分析器一致。

 

9.   功能四:索引库的护卫

9.1. 索引库的丰富

9.1.1.    步骤

向索引库中补充加document对象。

率先步:先创造一个indexwriter对象

其次步:创建一个document对象

其三步:把document对象写入索引库

第四步:关闭indexwriter。

 

9.1.2.    代码实现

//添加索引

     @Test

     public void addDocument() throws Exception {

          //索引库存放路径

          Directory directory = FSDirectory.open(new File("D:\\temp\\0108\\index"));

         

          IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, new IKAnalyzer());

          //创建一个indexwriter对象

          IndexWriter indexWriter = new IndexWriter(directory, config);

          //创建一个Document对象

          Document document = new Document();

          //向document对象中添加域。

          //不同的document可以有不同的域,同一个document可以有相同的域。

          document.add(new TextField("filename", "新添加的文档", Store.YES));

          document.add(new TextField("content", "新添加的文档的内容", Store.NO));

          document.add(new TextField("content", "新添加的文档的内容第二个content", Store.YES));

          document.add(new TextField("content1", "新添加的文档的内容要能看到", Store.YES));

          //添加文档到索引库

          indexWriter.addDocument(document);

          //关闭indexwriter

          indexWriter.close();

         

     }

 

9.2. 索引库删除

9.2.1.    删除所有

//删除全部索引

     @Test

     public void deleteAllIndex() throws Exception {

          IndexWriter indexWriter = getIndexWriter();

          //删除全部索引

          indexWriter.deleteAll();

          //关闭indexwriter

          indexWriter.close();

     }

 

证实:将引得目录的目录信息全刨除,直接彻底剔除,无法恢复。

 

此方法慎用!!

 

9.2.2.    指定询问条件去

//根据查询条件删除索引

     @Test

     public void deleteIndexByQuery() throws Exception {

          IndexWriter indexWriter = getIndexWriter();

          //创建一个查询条件

          Query query = new TermQuery(new Term("filename", "apache"));

          //根据查询条件删除

          indexWriter.deleteDocuments(query);

          //关闭indexwriter

          indexWriter.close();

     }

 

9.3. 索引库的改

规律就是是先行去后长。

//修改索引库

     @Test

     public void updateIndex() throws Exception {

          IndexWriter indexWriter = getIndexWriter();

          //创建一个Document对象

          Document document = new Document();

          //向document对象中添加域。

          //不同的document可以有不同的域,同一个document可以有相同的域。

          document.add(new TextField("filename", "要更新的文档", Store.YES));

          document.add(new TextField("content", "2013年11月18日 – Lucene 简介 Lucene 是一个基于 Java 的全文信息检索工具包,它不是一个完整的搜索应用程序,而是为你的应用程序提供索引和搜索功能。", Store.YES));

          indexWriter.updateDocument(new Term("content", "java"), document);

          //关闭indexWriter

          indexWriter.close();

     }

 

10.        Lucene索引库查询(重点)

        
对而物色的消息创建Query查询对象,Lucene会根据Query查询对象生成最终的查询语法,类似关系数据库Sql语法一样Lucene也出投机的查询语法,比如:“name:lucene”表示查询Field的name为“lucene”的文档信息。

         可通过简单栽方式创建查询对象:

         1)使用Lucene提供Query子类

        
Query是一个抽象类,lucene提供了广大询问对象,比如TermQuery项标准查询,NumericRangeQuery数字范围查询等。

         如下代码:

          Query query = new TermQuery(new Term(“name”,
“lucene”));

 

         2)使用QueryParse解析查询表达式

         QueryParse会将用户输入的询问表达式解析成Query对象实例。

         如下代码:

           QueryParser queryParser = new QueryParser(“name”,
new IKAnalyzer());

           Query query
= queryParser.parse(“name:lucene”);

 

 

10.1.    使用query的子类查询

10.1.1.          MatchAllDocsQuery

采用MatchAllDocsQuery查询索引目录中之具有文档

@Test

     public void testMatchAllDocsQuery() throws Exception {

          IndexSearcher indexSearcher = getIndexSearcher();

          //创建查询条件

          Query query = new MatchAllDocsQuery();

          //执行查询

          printResult(query, indexSearcher);

     }

 

10.1.2.          TermQuery

TermQuery,通过项查询,TermQuery不下分析器所以建议匹配不分词的Field域查询,比如订单号、分类ID号等。

指定要询问的地面和要查询的要词。

//使用Termquery查询

     @Test

     public void testTermQuery() throws Exception {

          IndexSearcher indexSearcher = getIndexSearcher();

          //创建查询对象

          Query query = new TermQuery(new Term("content", "lucene"));

          //执行查询

          TopDocs topDocs = indexSearcher.search(query, 10);

          //共查询到的document个数

          System.out.println("查询结果总数量:" + topDocs.totalHits);

          //遍历查询结果

          for (ScoreDoc scoreDoc : topDocs.scoreDocs) {

               Document document = indexSearcher.doc(scoreDoc.doc);

               System.out.println(document.get("filename"));

               //System.out.println(document.get("content"));

               System.out.println(document.get("path"));

               System.out.println(document.get("size"));

          }

          //关闭indexreader

          indexSearcher.getIndexReader().close();

     }

 

10.1.3.          NumericRangeQuery

可根据数值范围查询。

//数值范围查询

     @Test

     public void testNumericRangeQuery() throws Exception {

          IndexSearcher indexSearcher = getIndexSearcher();

          //创建查询

          //参数:

          //1.域名

          //2.最小值

          //3.最大值

          //4.是否包含最小值

          //5.是否包含最大值

          Query query = NumericRangeQuery.newLongRange("size", 1l, 1000l, true, true);

          //执行查询

          printResult(query, indexSearcher);

     }

 

10.1.4.          BooleanQuery

足整合查询条件。

//组合条件查询

     @Test

     public void testBooleanQuery() throws Exception {

          IndexSearcher indexSearcher = getIndexSearcher();

          //创建一个布尔查询对象

          BooleanQuery query = new BooleanQuery();

          //创建第一个查询条件

          Query query1 = new TermQuery(new Term("filename", "apache"));

          Query query2 = new TermQuery(new Term("content", "apache"));

          //组合查询条件

          query.add(query1, Occur.MUST);

          query.add(query2, Occur.MUST);

          //执行查询

          printResult(query, indexSearcher);

     }

 

Occur.MUST:必须满足这个标准,相当于and

Occur.SHOULD:应该满足,但是未满足呢得,相当给or

Occur.MUST_NOT:必须不满足。相当给not

 

 

10.2.    使用queryparser查询

透过QueryParser也得以创造Query,QueryParser提供一个Parse方法,此方可以一直冲查询语法来查询。Query对象执行的询问语法可经System.out.println(query);查询。

需用到分析器。建议创建索引时利用的分析器和查询索引时使用的分析器要一致。

 

10.2.1.          QueryParser

欲投入queryParser依赖的jar包。

 jQuery 15

 

1.1.1.1           程序实现

@Test

     public void testQueryParser() throws Exception {

          IndexSearcher indexSearcher = getIndexSearcher();

          //创建queryparser对象

          //第一个参数默认搜索的域

          //第二个参数就是分析器对象

          QueryParser queryParser = new QueryParser("content", new IKAnalyzer());

          Query query = queryParser.parse("Lucene是java开发的");

          //执行查询

          printResult(query, indexSearcher);

     }

 

1.1.1.2           查询语法

1、基础的查询语法,关键词查询:

域名+“:”+搜索的重中之重字

例如:content:java

2、范围查询

域名+“:”+[最小值 TO 最大值]

例如:size:[1 TO 1000]

限制查询在lucene中支持数值类,不支持字符串类型。在solr中支持字符串类型。

3、组合条件查询

1)+条件1 +条件jQuery2:两独标准化中是还要的关联and

例如:+filename:apache +content:apache

2)+条件1 原则2:必须满足第一只极,应该满足第二独规范

例如:+filename:apache content:apache

3)条件1 标准化2:两单原则满足这个即可。

例如:filename:apache content:apache

4)-条件1 口径2:必须不满足条件1,要满足条件2

例如:-filename:apache content:apache

Occur.MUST 查询条件必须满足,相当于and

+(加号)

Occur.SHOULD 查询条件可选,相当于or

 

空(不用符号)

Occur.MUST_NOT 查询条件不能满足,相当于not非

-(减号)

 

亚种写法:

条件1 AND 条件2

条件1 OR 条件2

条件1 NOT 条件2

 

10.2.2.          MultiFieldQueryParser

得指定多只默认搜索域

@Test

     public void testMultiFiledQueryParser() throws Exception {

          IndexSearcher indexSearcher = getIndexSearcher();

          //可以指定默认搜索的域是多个

          String[] fields = {"filename", "content"};

          //创建一个MulitFiledQueryParser对象

          MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields, new IKAnalyzer());

          Query query = queryParser.parse("java AND apache");

          System.out.println(query);

          //执行查询

          printResult(query, indexSearcher);

         

     }

 

 

 

txt

相关文章

网站地图xml地图