当前位置:  编程技术>移动开发
本页文章导读:
    ▪lucene-搜寻工具类        lucene--搜索工具类   搜索 1.创建搜索的索引目录 Directory directory = FSDirectory.open(new File("E:/Lucene/demo")); 2.创建搜索器 IndexSearcher searcher = IndexReader.open(directory); 3.创建搜索条件 Query query = new TermQ.........
    ▪ lucene 分词原理一        lucene 分词原理1   Lucene是一个高性能的java全文检索工具包,它使用的是倒排文件索引结构。该结构及相应的生成算法如下: 0)设有两篇文章1和2 文章1的内容为:Tom lives in Guangzhou,I live.........
    ▪ lucene 中的基本词       lucene 中的关键词 1.1 什么是lucene     Lucene是一个全文搜索框架,而不是应用产品。因此它并不像www.baidu.com 或者google Desktop那么拿来就能用,它只是提供了一种工具让你能实现这些产品.........

[1]lucene-搜寻工具类
    来源: 互联网  发布时间: 2014-02-18
lucene--搜索工具类

 

搜索

1.创建搜索的索引目录

Directory directory = FSDirectory.open(new File("E:/Lucene/demo"));

2.创建搜索器

IndexSearcher searcher = IndexReader.open(directory);

3.创建搜索条件

Query query = new TermQuery(new Term(field,value)); //索引域field中含有值value的内容

4.执行搜索

TopDocs topDocs = searcher.search(query,count); //根据searcher搜索并返回TopDocs 返回count条

5.根据TopDocs获取ScoreDoc对象数组

ScoreDoc[] scoreDocs = topDocs.scoreDocs;

6.遍历ScoreDoc数组获取Document对象

for (ScoreDoc sd : scoreDocs) {

Document doc = searcher.doc(sd.doc);

String name = doc.get("name");

}

7.关闭IndexSearcher

searcher.close();

 

重难点:

查询条件的选择:

1.精确查询,索引域field=value的内容

Query query = new TermQuery(new Term(field,value));

2.模糊查询字符串,索引域field中以start开始end结尾的内上下区间都包括的内容

Query query = new TermRangeQuery(field, start, end, true, true);

3.模糊查询数值,索引域field中以start开始end结尾的内上下区间都包括的内容

Query query = NumericRangeQuery.newFloatRange(field, min, max, true, true); //newDoubleRange/newIntRange/newLongRange

4.模糊查询以X为前缀的内容,索引域field中以value开头的内容

Query query = new PrefixQuery(new Term(field,value));

5.模糊查询—*通配符查询,索引域field中=*value*的内容,分三种情况,*value/value*/*value*

Query query = new WildcardQuery(new Term(field,value));

6.

 

 

单例的Directory和IndexReader和IndexSearcher

 

private static IndexReader reader;

private static Directory directory;

 

static{

try {

//索引目录

directory = FSDirectory.open(new File("E:/Lucene/demo"));

//读取器

reader = IndexReader.open(directory);

} catch (CorruptIndexException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

 

/**

 * 获取查询器

 * @return

 * @author:qiuchen

 */

public static IndexSearcher getSearcher(){

try {

if(reader == null){

reader = IndexReader.open(directory);

}else{

//如果reader发生变化,重新创建

IndexReader ir = IndexReader.openIfChanged(reader);

if(ir != null){

reader.close(); //把原来的reader关闭

reader = ir; //重新给reader赋值

}

}

return new IndexSearcher(reader);

} catch (CorruptIndexException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

 

/**

 * 关闭查询器

 * @author:qiuchen

 */

public static void closeSearch(IndexSearcher searcher){

try {

if(searcher != null)

searcher.close();

} catch (IOException e) {

e.printStackTrace();

}

}


    
[2] lucene 分词原理一
    来源: 互联网  发布时间: 2014-02-18
lucene 分词原理1

 

Lucene是一个高性能的java全文检索工具包,它使用的是倒排文件索引结构。该结构及相应的生成算法如下: 

0)设有两篇文章1和2 
文章1的内容为:Tom lives in Guangzhou,I live in Guangzhou too. 
文章2的内容为:He once lived in Shanghai. 

1)由于lucene是基于关键词索引和查询的,首先我们要取得这两篇文章的关键词,通常我们需要如下处理措施 
a.我们现在有的是文章内容,即一个字符串,我们先要找出字符串中的所有单词,即分词。英文单词由于用空格分隔,比较好处理。中文单词间是连在一起的需要特殊的分词处理。 
b.文章中的”in”, “once” “too”等词没有什么实际意义,中文中的“的”“是”等字通常也无具体含义,这些不代表概念的词可以过滤掉 
c.用户通常希望查“He”时能把含“he”,“HE”的文章也找出来,所以所有单词需要统一大小写。 
d.用户通常希望查“live”时能把含“lives”,“lived”的文章也找出来,所以需要把“lives”,“lived”还原成“live” 
e.文章中的标点符号通常不表示某种概念,也可以过滤掉 
在lucene中以上措施由Analyzer类完成 

经过上面处理后 
文章1的所有关键词为:[tom] [live] [guangzhou] [i] [live] [guangzhou] 
文章2的所有关键词为:[he] [live] [shanghai] 

2) 有了关键词后,我们就可以建立倒排索引了。上面的对应关系是:“文章号”对“文章中所有关键词”。倒排索引把这个关系倒过来,变成:“关键词”对“拥有该关键词的所有文章号”。文章1,2经过倒排后变成 
关键词 文章号 
guangzhou 1 
he 2 
i 1 
live 1,2 
shanghai 2 
tom 1 

通常仅知道关键词在哪些文章中出现还不够,我们还需要知道关键词在文章中出现次数和出现的位置,通常有两种位置:

a)字符位置,即记录该词是文章中第几个字符(优点是关键词亮显时定位快);

b)关键词位置,即记录该词是文章中第几个关键词(优点是节约索引空间、词组(phase)查询快),lucene中记录的就是这种位置。 

加上“出现频率”和“出现位置”信息后,我们的索引结构变为: 
关键词 文章号[出现频率] 出现位置 
guangzhou 1[2] 3,6 
he 2[1] 1 
i 1[1] 4 
live 1[2],2[1] 2,5,2 
shanghai 2[1] 3 
tom 1[1] 1 

以live 这行为例我们说明一下该结构:live在文章1中出现了2次,文章2中出现了一次,它的出现位置为“2,5,2”这表示什么呢?我们需要结合文章号和出现频率来分析,文章1中出现了2次,那么“2,5”就表示live在文章1中出现的两个位置,文章2中出现了一次,剩下的“2”就表示live是文章2中第 2个关键字。 

以上就是lucene索引结构中最核心的部分。我们注意到关键字是按字符顺序排列的(lucene没有使用B树结构),因此lucene可以用二元搜索算法快速定位关键词。 

实现时 lucene将上面三列分别作为词典文件(Term Dictionary)、频率文件(frequencies)、位置文件 (positions)保存。其中词典文件不仅保存有每个关键词,还保留了指向频率文件和位置文件的指针,通过指针可以找到该关键字的频率信息和位置信息。 

Lucene中使用了field的概念,用于表达信息所在位置(如标题中,文章中,url中),在建索引中,该field信息也记录在词典文件中,每个关键词都有一个field信息(因为每个关键字一定属于一个或多个field)。 

为了减小索引文件的大小,Lucene对索引还使用了压缩技术。首先,对词典文件中的关键词进行了压缩,关键词压缩为<前缀长度,后缀>,例如:当前词为“阿拉伯语”,上一个词为“阿拉伯”,那么“阿拉伯语”压缩为<3,语>。其次大量用到的是对数字的压缩,数字只保存与上一个值的差值(这样可以减小数字的长度,进而减少保存该数字需要的字节数)。例如当前文章号是16389(不压缩要用3个字节保存),上一文章号是16382,压缩后保存7(只用一个字节)。 

下面我们可以通过对该索引的查询来解释一下为什么要建立索引。 
假设要查询单词 “live”,lucene先对词典二元查找、找到该词,通过指向频率文件的指针读出所有文章号,然后返回结果。词典通常非常小,因而,整个过程的时间是毫秒级的。 
而用普通的顺序匹配算法,不建索引,而是对所有文章的内容进行字符串匹配,这个过程将会相当缓慢,当文章数目很大时,时间往往是无法忍受的。 


    
[3] lucene 中的基本词
    来源: 互联网  发布时间: 2014-02-18
lucene 中的关键词

1.1 什么是lucene 
    Lucene是一个全文搜索框架,而不是应用产品。因此它并不像www.baidu.com 或者google Desktop那么拿来就能用,它只是提供了一种工具让你能实现这些产品。 
2 lucene的工作方式 
    lucene提供的服务实际包含两部分:一入一出。所谓入是写入,即将你提供的源(本质是字符串)写入索引或者将其从索引中删除;所谓出是读出,即向用户提供全文搜索服务,让用户可以通过关键词定位源。 
2.1写入流程 
    源字符串首先经过analyzer处理,包括:分词,分成一个个单词;去除stopword(可选)。 
将源中需要的信息加入Document的各个Field中,并把需要索引的Field索引起来,把需要存储的Field存储起来。 
    将索引写入存储器,存储器可以是内存或磁盘。 
2.2读出流程 
    用户提供搜索关键词,经过analyzer处理。 
对处理后的关键词搜索索引找出对应的Document。 
用户根据需要从找到的Document中提取需要的Field。 
3 一些需要知道的概念 
3.1 analyzer 
    Analyzer是分析器,它的作用是把一个字符串按某种规则划分成一个个词语,并去除其中的无效词语,这里说的无效词语是指英文中的“of”、“the”,中文中的“的”、“地”等词语,这些词语在文章中大量出现,但是本身不包含什么关键信息,去掉有利于缩小索引文件、提高效率、提高命中率。 
  分词的规则千变万化,但目的只有一个:按语义划分。这点在英文中比较容易实现,因为英文本身就是以单词为单位的,已经用空格分开;而中文则必须以某种方法将连成一片的句子划分成一个个词语。具体划分方法下面再详细介绍,这里只需了解分析器的概念即可。 
3.2 document 
  用户提供的源是一条条记录,它们可以是文本文件、字符串或者数据库表的一条记录等等。一条记录经过索引之后,就是以一个Document的形式存储在索引文件中的。用户进行搜索,也是以Document列表的形式返回。 
3.3 field 
    一个Document可以包含多个信息域,例如一篇文章可以包含“标题”、“正文”、“最后修改时间”等信息域,这些信息域就是通过Field在Document中存储的。 
    Field有两个属性可选:存储和索引。通过存储属性你可以控制是否对这个Field进行存储;通过索引属性你可以控制是否对该Field进行索引。这看起来似乎有些废话,事实上对这两个属性的正确组合很重要,下面举例说明:还是以刚才的文章为例子,我们需要对标题和正文进行全文搜索,所以我们要把索引属性设置为真,同时我们希望能直接从搜索结果中提取文章标题,所以我们把标题域的存储属性设置为真,但是由于正文域太大了,我们为了缩小索引文件大小,将正文域的存储属性设置为假,当需要时再直接读取文件;我们只是希望能从搜索解果中提取最后修改时间,不需要对它进行搜索,所以我们把最后修改时间域的存储属性设置为真,索引属性设置为假。上面的三个域涵盖了两个属性的三种组合,还有一种全为假的没有用到,事实上Field不允许你那么设置,因为既不存储又不索引的域是没有意义的。 
3.4 term 
  term是搜索的最小单位,它表示文档的一个词语,term由两部分组成:它表示的词语和这个词语所出现的field。 
3.5 tocken 
    tocken是term的一次出现,它包含trem文本和相应的起止偏移,以及一个类型字符串。一句话中可以出现多次相同的词语,它们都用同一个term表示,但是用不同的tocken,每个tocken标记该词语出现的地方。 
3.6 segment 
    添加索引时并不是每个document都马上添加到同一个索引文件,它们首先被写入到不同的小文件,然后再合并成一个大索引文件,这里每个小文件都是一个segment。 
4 如何建索引 
4.1 最简单的能完成索引的代码片断 
IndexWriter writer = new IndexWriter(“/data/index/”, new StandardAnalyzer(), true); 
Document doc = new Document(); 
doc.add(new Field("title", "lucene introduction", Field.Store.YES, Field.Index.TOKENIZED)); 
doc.add(new Field("content", "lucene works well", Field.Store.YES, Field.Index.TOKENIZED)); 
writer.addDocument(doc); 
writer.optimize(); 
writer.close(); 
下面我们分析一下这段代码。 
首先我们创建了一个writer,并指定存放索引的目录为“/data/index”,使用的分析器为StandardAnalyzer,第三个参数说明如果已经有索引文件在索引目录下,我们将覆盖它们。然后我们新建一个document。 
  我们向document添加一个field,名字是“title”,内容是“lucene introduction”,对它进行存储并索引。再添加一个名字是“content”的field,内容是“lucene works well”,也是存储并索引。 
然后我们将这个文档添加到索引中,如果有多个文档,可以重复上面的操作,创建document并添加。 
添加完所有document,我们对索引进行优化,优化主要是将多个segment合并到一个,有利于提高索引速度。 
   随后将writer关闭,这点很重要。 
   对,创建索引就这么简单! 
  当然你可能修改上面的代码获得更具个性化的服务。 
4.2 索引文本文件 
    如果你想把纯文本文件索引起来,而不想自己将它们读入字符串创建field,你可以用下面的代码创建field: 
Field field = new Field("content", new FileReader(file)); 
    这里的file就是该文本文件。该构造函数实际上是读去文件内容,并对其进行索引,但不存储。 


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解 iis7站长之家
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3