- 浏览: 150292 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (69)
- Maven (1)
- lucene (22)
- bobo zoie (6)
- eclipse (5)
- Nexus (1)
- Git (1)
- trac (1)
- RMI (2)
- svn (0)
- Protocol buffer (0)
- sensei (6)
- JMX (2)
- Faceted search (1)
- Linux (1)
- Cassandra (1)
- Zookeeper (3)
- zoie (1)
- jmap (1)
- mongodb (2)
- 百度百科 (2)
- 词库 (2)
- 抓取 (2)
- IndexTank (1)
- LinkedIn (4)
- norbert (3)
- 分布式 (2)
- senseidb (2)
- Thrift (1)
- scala (1)
- 搜索引擎 (1)
- 质量 (1)
- Nosql (1)
- Jaccard (1)
- Mahout (1)
最新评论
-
bluky999:
@Mark
怎样量化评价搜索引擎的结果质量 -
baso4233:
非常感谢,我跑通了。途中出现了,java.lang.Unsup ...
norbert 高并发分布式服务例子 examples (二) -
yangsong158:
rabbit9898 写道xiansuanla 写道我运行 m ...
JMX 入门例子 -
rabbit9898:
xiansuanla 写道我运行 main方法以后 cmd 里 ...
JMX 入门例子 -
xiansuanla:
我运行 main方法以后 cmd 里面运行 jconsole ...
JMX 入门例子
一、lucene索引的建立
1.索引文件
.fdt文件:主要保存数据源数据,存储的field的值仅为Document中具有的Store.YES属性的field
.fdx文件:记录当前Document在.fdt文件中的位置,以便后面读取时方便
segments文件:通常,在一个完整的索引中,有且只有一个segments文件,该文件没有后缀,它记录了当前索引中所有的
segment的信息
.fnm文件:包含了Document中的所有field名称
.tis文件:用于存储分词后的词条(Term);
.tii文件:是.tis文件的索引文件,它标明了每个.tis文件中的词条的位置
deletable文件:类似于Windows的回收站原理,所有的文档在被删除后,会首先在deletable文件中留一个记录,要真正删
除时,才将索引除去。
2.文档倒排
作用:统计词条的位置和词频信息
说明:倒排完毕后,所有的词条都被放入到了一个HashTable中,它的key是词条的Term对象,value是Posting类型的对象
lucene首先将这个HashTable转化成一个Posting类型的数组,然后对这个数组进行排序,使所有的词条按字典顺序
排列。那样,就可以将词条信息写入到.tii和.tis文件中。另外,将频率和位置信息写入.frq和.prx文件中去
3.StandardAnalyzer能将标点过滤掉
4.FSDirectory和RAMDirectory
FSDirectory:指的是在文件系统中的一个路径
RAMDirectory:是内存中的一个区域
二者都可以作为索引的存储路径
5.合并索引
用户不但可以将存放于不同文件系统路径下的索引合并,还可以将内存中的索引与文件系统中的索引进行合并,以次来
保存那些存放于RAMDirectory中的索引
注意:合并内存中的索引时,一定要先将其相应的IndexWriter关闭,以保证滞留在缓存中的文档被刷到RAMDirectory中
去,这点与试用FSDirectory时一样。如果不使用close方法关闭IndexWriter,就会发现索引文件并未真正写入目
录中去。
合并索引的目的:是为了减少目录内的索引文件的数量,以使lucene能够更快地处理索引,这将大大加快lucene的检索速
度。
6.索引的优化
目的:对整个索引目录内、未合并的segment进行一个优化的合并,以保证检索时的速度
IndexWriter的optimize()方法能够对当前IndexWriter所指定的索引目录及其所使用的缓存目录下的所有的segment做优化
使所有的segment合并成一个完整的segment,即整个索引目录内只出现一种文件前缀
7.试用文档ID号来删除特定文档
逻辑删除:(相当于windows的回收站)
IndexReader reader=IndexReader(INDEX_STORE_PATH);
reader.deleteDocument(0);
reader.close();
逻辑删除后恢复:
IndexReader reader=IndexReader(INDEX_STORE_PATH);
reader.undeleteAll();
reader.close();
物理删除:
IndexReader reader=IndexReader(INDEX_STORE_PATH);
reader.optimize();
reader.close();
8.lucene索引的同步问题
a. lucene的同步问题只可能发生在对索引进行文档添加、文档删除、合并segment和优化时
b. lucene有自己的锁机制可以防止非法操作的发生
write.lock出现在向索引添加文档时,或是将文档从索引中删除时
commit.lock主要是与segment合并和读取的操作相关
c. 开发者在开发应用的过程中,不能仅仅依赖于lucene的锁机制来防止非法操作的发生,而
是应该养成良好的编写具有同步特性的代码的习惯,才能编写出高质量的代码
9. lucene2.0以上的版本中出现了个新类,indexModifier类,它集成了IndexWriter的大部分功
能和IndexReader中的对索引删除的功能
二、lucene的搜索
1.几个基础类简要介绍
.Query:表示一次查询
.Hits:表示一次查询的结果
.Filter:表示对索引中文档集合的过滤器,它使检索在某一个文档集合的子集中进行
.Sort:对索引的结果进行排序的工具
.HitCollector:对检索结果进行选择的一个工具,并将选择后的结果保存在其中
.Weight:就是"权重",表示一次查询时,索引中的某个文档的重要性
2.IndexSearcher类search方法可以分为三组
第一组:
public final Hits search(Query query)
public Hits search(Query query, Filter filter)
public Hits search(Query query, Sort sort)
返回值为一个Hits型的对象,它们通过一个Query对象,在索引中检索相关的文档,并返回检索
的结果
第二组:
public TopFieldDocs search(Query query, Filter filter, int n,Sort sort)
public TopDocs search(Weight weight, Filter filter, final int nDocs)
public TopFieldDocs search(Weight weight, Filter filter, final int nDocs,Sort sort)
public TopDocs search(Query query, Filter filter, int n)
返回的是TopDocs类型和TopFieldDocs(是TopDocs的一个子类)类型,它们表示索引中得分较高的文
档集合,该组方法中都带有一个int型的参数,它表示取出置于TopDocs集合中的文档的数量
第三组:
public void search(Query query, HitCollector results)
public void search(Query query, Filter filter, HitCollector results)
public void search(Weight weight, Filter filter,final HitCollector results)
返回值为空,但是并不是说它们不具备返回值的功能,这一组方法的参数中,都有一个HitCollector
类型的参数,该参数表示由这一组方法检索而返回的结果,将被保存在这个HitCollector对象中
3.Hits内部缓存
Hits的缓存是一个Vector类型的对象,默认存放200个文档数量,如果当前链表的文档数量大于规定
的数量,则从中删除最后一个也就是不常使用的一个,如果缓存中没有或者是缓存不慎丢失,则从
searcher中重新取回Document
4.Query搜索相关
Query类是个抽象类
它有如下几种子类
TermQuery:词条搜索,它是lucene内最为简单也是最为原子的一种搜索方式。通过对某个固定词条的
指定,它实现了检索索引中存在的该词条的所有文档
BooleanQuery:布尔型查询就是一个由多个子句和子句(默认的最大子句数为1024,如果超过了这个数量,
会抛出TooManyClauses异常,用户可以通过BooleanQuery.setMaxClauseCount(int MaxClauseCount)
去更改其最大的子句数量)间的布尔逻辑所组成的查询,各种子句间都是如"与","或"这样的布尔
逻辑。布尔逻辑由三种情况去任意组合,它们分别是BooleanClause.Qccur.MUST
BooleanClause.Qccur.MUST_NOT BooleanClause.Qccur.SHOULD
RangeQuery:提供对一定范围内的文档进行查找的途径,这种范围可以是时间、日期、数字大小等。
PrifixQuery:根据前缀进行查找
PhraseQuery:短语搜索,对一个或多个关键字进行搜索。PhraseQuery.setSlop(int i)可以设定关键字
中允许插入无关的字的个数
MultiPhraseQuery:可以对多个短语同时进行搜索,指定前缀或后缀,或者同时指定前缀和后缀的搜索。
FuzzyQuery:模糊搜索,可以帮助用户进行单字的模糊查找,这里有个相似度的概念,它决定模糊匹配
时的严格程度。默认的相似度是0.5,当这个值越小时,通过模糊查找出的文档的匹配程度就越低
文档的数量也就越多,反之亦然。
WildcardQuery:通配符搜索,"*"表示0到多个字符,"?"表示一个单一的字符
SpanQuery:跨度搜索,这里的跨度是指一种数据源中每个词条的位置所构成的一个跨度
5.多域搜索(MultiFieldQueryParser)和多索引搜索(MultiSearcher)
每次构造一个IndexSearcher的实例时,只能打开一个索引就行搜索。如果此时系统的环境使用了多索
引目录的结构,即用户希望检索到的数据,可能被存放于多个索引目录随机的一个中,这样就无法进行检索
了,这时就必须借助于多域搜索MultiFieldQueryParser和多索引搜索MultiSearcher
注意:MultiSearcher是利用一个for循环将所有的IndexSearcher对象取出,然后顺序循环搜索并得出
结果,最后将结果合并返回给用户,在这个过程中,始终只有一个索引被搜索,其它索引目录处于等待状态
多线程搜索(ParalellMultiSearcher)可以很好的解决这个问题,一旦一个搜索的请求发出,所有索引可以
在同一时刻被检索,也就是被多个线程检索。这样,可以省去排队等待的时间,提高检索效率。但是实际情
况并非如此,结测试单核CPU和双核CPU环境中,ParalellMultiSearcher比MultiSearcher的检索效率要低
问题的根源可能是Lucene没有为ParalellMultiSearcher开设一个专门的线程池。这样每次都需要实例化新
线程,导致了性能的降低。
6.跨虚拟机器的搜索
java中的RMI提供了调用远程虚拟机中的对象方法的能力。可以通过RMI,获取远程虚拟机中的对象存根Stub
然后调用它的方法,并在远程虚拟机内执行,最后将结果返回本机进行处理。
三、排序过滤和分页
仅仅把东西搜出来是不够的,好的检索工具还应当能够对检索的结果进行排序,优先将最相关的内容送出
或是按照某种规则,将检索结果送出。
1.文档得分规则
文档得分主要是由4部分内容来决定,即tf(词条频率)、idf(反转文档频率)、boost(Field的激励因子)
和lengthNorm(长度因子)
tf:某个关键字在某文档中出现次数的平方根
idf:Math.log(numDocs/docFreq+1)+1.0 (numDocs:表示索引中总共的文档数量,docFreq:当前检索
的关键字的文档总数)
lengthNorm:在lucene的底层实现中,lengthNorm是一种固定值,它无需在索引时指定,只需要跟随创建
索引过程,被写入索引中。
boost:文档的boost值一般情况下默认为1.0,在建立索引时可通过预先人为的指定Document或Field的
boost值,来改变搜索时文档的得分,从而改变文档在搜索结果中的排序位置。
2.使用Sort排序
该类有6种构造函数
public Sort()
public Sort(String field) 默认为降序
public Sort(String field,boolean reverse)
public Sort(String[] fields)
public Sort(SortField field)
public Sort(SortField[] fields)
Sort可以对单一的Field进行排序,但是对多个Field的排序就必须要借助SortField类了。SortField类
是个包装类,它能描述Field和reverse(排序)信息,在搜索结果中有很多记录时,应该正确的指定Field
的类型,这样对排序过程的效率会有很大的提高。
排序有多种
a.按文档得分进行排序:这是lucene默认的排序方式
如:Hits hist=searcher.search(q,Sort.RELEVANCE); Sort.RELEVANCE表示当前的排序法则
是按照文档的得分进行降序排列
b.按文档的内部ID号来排序:在建立索引的时候,lucene会为每个文档建立一个内部的ID号
如:Hits hits=searcher.search(q,Sort.INDEXORDER) Sort.INDEXORDER表示排序法则是按
照文档的内部ID号来排序
c.按一个或多个Field来排序:把每个Field封装成SortField,然后以SortField[]数组的形式传入Sort类
注意:比较字符串时,Locale信息的不同,很有可能会影响到比较的结果,因此SortField类有这样的构
造函数,可以帮助指定Locale信息
public SortField(String field,Locale locale)
public SortField(String field,Locale locale,boolean reverse)
当指定Locale后,lucene才可以正确的对字符串进行比较,从而正确的排序。不过大多数情况下,使用Sort
进行排序时,排序的内容多为int型或是日期型。即便需要进行字符串的比较,也最好使用仅包含ASCII的
字符串Field进行,这样可以确保排序的正确,同时,尽量提高排序的效率。
3.搜索时使用过滤器
简单示例:
public class MySecurityFilter extends Filter{
public static final int SECURITY=0;
public BitSet bits(IndexReader reader) throws IOException{
//先初始化一个BitSet对象
final BitSet bits=new BitSet(reader.maxDoc());
//将整个集合置为true,表示当前集合内的所有文档都是可以被检索到的
bits.set(0,bits.size()-1);
//构造一个Term对象,代表最高安全级别
Term term=new Term("securitylevel",SECURITY+"");
//从索引中取出具有最高安全级别的文档
TermDocs termDocs=reader.termDocs(term);
//遍历每个文档
while(termDocs.next()){
bits.set(termDocs.doc(),false);
}
retrun bits;
}
}
or
public class MySecurityFilter extends Filter{
public static final int SECURITY=0;
public BitSet bits(IndexReader reader) throws IOException{
//先初始化一个BitSet对象
final BitSet bits=new BitSet(reader.maxDoc());
//将整个集合置为true,表示当前集合内的所有文档都是可以被检索到的
bits.set(0,bits.size()-1);
//构造一个Term对象,代表最高安全级别
Term term=new Term("securitylevel",SECURITY+"");
//初始化一个IndexSearcher对象
//查找securitylevel这个Field的值为SECURITY的文档
IndexSearcher searcher=new IndexSearcher(term);
Hits hits=searcher.search(new TermQuery(term));
for(int i=0;i<hits.length();i++){
bits.set(hits.id(i),false);
}
retrun bits;
}
}
注意:Filter实际上在进行真正的查询之前,已经遍历过一次一遍索引了,因此无
论使用何种Filter,都不应该忽视它对查询效率的影响。
4.在结果中查询(QueryFilter)
在QueryFilter的bits方法中,调用IndexSearcher方法,对注入的Query进行一次
检索,然后在要被返回的BitSet中,将检索结果所对应的文档标记为true,即过滤掉了
所有不再检索结果范围内的文档。
1.索引文件
.fdt文件:主要保存数据源数据,存储的field的值仅为Document中具有的Store.YES属性的field
.fdx文件:记录当前Document在.fdt文件中的位置,以便后面读取时方便
segments文件:通常,在一个完整的索引中,有且只有一个segments文件,该文件没有后缀,它记录了当前索引中所有的
segment的信息
.fnm文件:包含了Document中的所有field名称
.tis文件:用于存储分词后的词条(Term);
.tii文件:是.tis文件的索引文件,它标明了每个.tis文件中的词条的位置
deletable文件:类似于Windows的回收站原理,所有的文档在被删除后,会首先在deletable文件中留一个记录,要真正删
除时,才将索引除去。
2.文档倒排
作用:统计词条的位置和词频信息
说明:倒排完毕后,所有的词条都被放入到了一个HashTable中,它的key是词条的Term对象,value是Posting类型的对象
lucene首先将这个HashTable转化成一个Posting类型的数组,然后对这个数组进行排序,使所有的词条按字典顺序
排列。那样,就可以将词条信息写入到.tii和.tis文件中。另外,将频率和位置信息写入.frq和.prx文件中去
3.StandardAnalyzer能将标点过滤掉
4.FSDirectory和RAMDirectory
FSDirectory:指的是在文件系统中的一个路径
RAMDirectory:是内存中的一个区域
二者都可以作为索引的存储路径
5.合并索引
用户不但可以将存放于不同文件系统路径下的索引合并,还可以将内存中的索引与文件系统中的索引进行合并,以次来
保存那些存放于RAMDirectory中的索引
注意:合并内存中的索引时,一定要先将其相应的IndexWriter关闭,以保证滞留在缓存中的文档被刷到RAMDirectory中
去,这点与试用FSDirectory时一样。如果不使用close方法关闭IndexWriter,就会发现索引文件并未真正写入目
录中去。
合并索引的目的:是为了减少目录内的索引文件的数量,以使lucene能够更快地处理索引,这将大大加快lucene的检索速
度。
6.索引的优化
目的:对整个索引目录内、未合并的segment进行一个优化的合并,以保证检索时的速度
IndexWriter的optimize()方法能够对当前IndexWriter所指定的索引目录及其所使用的缓存目录下的所有的segment做优化
使所有的segment合并成一个完整的segment,即整个索引目录内只出现一种文件前缀
7.试用文档ID号来删除特定文档
逻辑删除:(相当于windows的回收站)
IndexReader reader=IndexReader(INDEX_STORE_PATH);
reader.deleteDocument(0);
reader.close();
逻辑删除后恢复:
IndexReader reader=IndexReader(INDEX_STORE_PATH);
reader.undeleteAll();
reader.close();
物理删除:
IndexReader reader=IndexReader(INDEX_STORE_PATH);
reader.optimize();
reader.close();
8.lucene索引的同步问题
a. lucene的同步问题只可能发生在对索引进行文档添加、文档删除、合并segment和优化时
b. lucene有自己的锁机制可以防止非法操作的发生
write.lock出现在向索引添加文档时,或是将文档从索引中删除时
commit.lock主要是与segment合并和读取的操作相关
c. 开发者在开发应用的过程中,不能仅仅依赖于lucene的锁机制来防止非法操作的发生,而
是应该养成良好的编写具有同步特性的代码的习惯,才能编写出高质量的代码
9. lucene2.0以上的版本中出现了个新类,indexModifier类,它集成了IndexWriter的大部分功
能和IndexReader中的对索引删除的功能
二、lucene的搜索
1.几个基础类简要介绍
.Query:表示一次查询
.Hits:表示一次查询的结果
.Filter:表示对索引中文档集合的过滤器,它使检索在某一个文档集合的子集中进行
.Sort:对索引的结果进行排序的工具
.HitCollector:对检索结果进行选择的一个工具,并将选择后的结果保存在其中
.Weight:就是"权重",表示一次查询时,索引中的某个文档的重要性
2.IndexSearcher类search方法可以分为三组
第一组:
public final Hits search(Query query)
public Hits search(Query query, Filter filter)
public Hits search(Query query, Sort sort)
返回值为一个Hits型的对象,它们通过一个Query对象,在索引中检索相关的文档,并返回检索
的结果
第二组:
public TopFieldDocs search(Query query, Filter filter, int n,Sort sort)
public TopDocs search(Weight weight, Filter filter, final int nDocs)
public TopFieldDocs search(Weight weight, Filter filter, final int nDocs,Sort sort)
public TopDocs search(Query query, Filter filter, int n)
返回的是TopDocs类型和TopFieldDocs(是TopDocs的一个子类)类型,它们表示索引中得分较高的文
档集合,该组方法中都带有一个int型的参数,它表示取出置于TopDocs集合中的文档的数量
第三组:
public void search(Query query, HitCollector results)
public void search(Query query, Filter filter, HitCollector results)
public void search(Weight weight, Filter filter,final HitCollector results)
返回值为空,但是并不是说它们不具备返回值的功能,这一组方法的参数中,都有一个HitCollector
类型的参数,该参数表示由这一组方法检索而返回的结果,将被保存在这个HitCollector对象中
3.Hits内部缓存
Hits的缓存是一个Vector类型的对象,默认存放200个文档数量,如果当前链表的文档数量大于规定
的数量,则从中删除最后一个也就是不常使用的一个,如果缓存中没有或者是缓存不慎丢失,则从
searcher中重新取回Document
4.Query搜索相关
Query类是个抽象类
它有如下几种子类
TermQuery:词条搜索,它是lucene内最为简单也是最为原子的一种搜索方式。通过对某个固定词条的
指定,它实现了检索索引中存在的该词条的所有文档
BooleanQuery:布尔型查询就是一个由多个子句和子句(默认的最大子句数为1024,如果超过了这个数量,
会抛出TooManyClauses异常,用户可以通过BooleanQuery.setMaxClauseCount(int MaxClauseCount)
去更改其最大的子句数量)间的布尔逻辑所组成的查询,各种子句间都是如"与","或"这样的布尔
逻辑。布尔逻辑由三种情况去任意组合,它们分别是BooleanClause.Qccur.MUST
BooleanClause.Qccur.MUST_NOT BooleanClause.Qccur.SHOULD
RangeQuery:提供对一定范围内的文档进行查找的途径,这种范围可以是时间、日期、数字大小等。
PrifixQuery:根据前缀进行查找
PhraseQuery:短语搜索,对一个或多个关键字进行搜索。PhraseQuery.setSlop(int i)可以设定关键字
中允许插入无关的字的个数
MultiPhraseQuery:可以对多个短语同时进行搜索,指定前缀或后缀,或者同时指定前缀和后缀的搜索。
FuzzyQuery:模糊搜索,可以帮助用户进行单字的模糊查找,这里有个相似度的概念,它决定模糊匹配
时的严格程度。默认的相似度是0.5,当这个值越小时,通过模糊查找出的文档的匹配程度就越低
文档的数量也就越多,反之亦然。
WildcardQuery:通配符搜索,"*"表示0到多个字符,"?"表示一个单一的字符
SpanQuery:跨度搜索,这里的跨度是指一种数据源中每个词条的位置所构成的一个跨度
5.多域搜索(MultiFieldQueryParser)和多索引搜索(MultiSearcher)
每次构造一个IndexSearcher的实例时,只能打开一个索引就行搜索。如果此时系统的环境使用了多索
引目录的结构,即用户希望检索到的数据,可能被存放于多个索引目录随机的一个中,这样就无法进行检索
了,这时就必须借助于多域搜索MultiFieldQueryParser和多索引搜索MultiSearcher
注意:MultiSearcher是利用一个for循环将所有的IndexSearcher对象取出,然后顺序循环搜索并得出
结果,最后将结果合并返回给用户,在这个过程中,始终只有一个索引被搜索,其它索引目录处于等待状态
多线程搜索(ParalellMultiSearcher)可以很好的解决这个问题,一旦一个搜索的请求发出,所有索引可以
在同一时刻被检索,也就是被多个线程检索。这样,可以省去排队等待的时间,提高检索效率。但是实际情
况并非如此,结测试单核CPU和双核CPU环境中,ParalellMultiSearcher比MultiSearcher的检索效率要低
问题的根源可能是Lucene没有为ParalellMultiSearcher开设一个专门的线程池。这样每次都需要实例化新
线程,导致了性能的降低。
6.跨虚拟机器的搜索
java中的RMI提供了调用远程虚拟机中的对象方法的能力。可以通过RMI,获取远程虚拟机中的对象存根Stub
然后调用它的方法,并在远程虚拟机内执行,最后将结果返回本机进行处理。
三、排序过滤和分页
仅仅把东西搜出来是不够的,好的检索工具还应当能够对检索的结果进行排序,优先将最相关的内容送出
或是按照某种规则,将检索结果送出。
1.文档得分规则
文档得分主要是由4部分内容来决定,即tf(词条频率)、idf(反转文档频率)、boost(Field的激励因子)
和lengthNorm(长度因子)
tf:某个关键字在某文档中出现次数的平方根
idf:Math.log(numDocs/docFreq+1)+1.0 (numDocs:表示索引中总共的文档数量,docFreq:当前检索
的关键字的文档总数)
lengthNorm:在lucene的底层实现中,lengthNorm是一种固定值,它无需在索引时指定,只需要跟随创建
索引过程,被写入索引中。
boost:文档的boost值一般情况下默认为1.0,在建立索引时可通过预先人为的指定Document或Field的
boost值,来改变搜索时文档的得分,从而改变文档在搜索结果中的排序位置。
2.使用Sort排序
该类有6种构造函数
public Sort()
public Sort(String field) 默认为降序
public Sort(String field,boolean reverse)
public Sort(String[] fields)
public Sort(SortField field)
public Sort(SortField[] fields)
Sort可以对单一的Field进行排序,但是对多个Field的排序就必须要借助SortField类了。SortField类
是个包装类,它能描述Field和reverse(排序)信息,在搜索结果中有很多记录时,应该正确的指定Field
的类型,这样对排序过程的效率会有很大的提高。
排序有多种
a.按文档得分进行排序:这是lucene默认的排序方式
如:Hits hist=searcher.search(q,Sort.RELEVANCE); Sort.RELEVANCE表示当前的排序法则
是按照文档的得分进行降序排列
b.按文档的内部ID号来排序:在建立索引的时候,lucene会为每个文档建立一个内部的ID号
如:Hits hits=searcher.search(q,Sort.INDEXORDER) Sort.INDEXORDER表示排序法则是按
照文档的内部ID号来排序
c.按一个或多个Field来排序:把每个Field封装成SortField,然后以SortField[]数组的形式传入Sort类
注意:比较字符串时,Locale信息的不同,很有可能会影响到比较的结果,因此SortField类有这样的构
造函数,可以帮助指定Locale信息
public SortField(String field,Locale locale)
public SortField(String field,Locale locale,boolean reverse)
当指定Locale后,lucene才可以正确的对字符串进行比较,从而正确的排序。不过大多数情况下,使用Sort
进行排序时,排序的内容多为int型或是日期型。即便需要进行字符串的比较,也最好使用仅包含ASCII的
字符串Field进行,这样可以确保排序的正确,同时,尽量提高排序的效率。
3.搜索时使用过滤器
简单示例:
public class MySecurityFilter extends Filter{
public static final int SECURITY=0;
public BitSet bits(IndexReader reader) throws IOException{
//先初始化一个BitSet对象
final BitSet bits=new BitSet(reader.maxDoc());
//将整个集合置为true,表示当前集合内的所有文档都是可以被检索到的
bits.set(0,bits.size()-1);
//构造一个Term对象,代表最高安全级别
Term term=new Term("securitylevel",SECURITY+"");
//从索引中取出具有最高安全级别的文档
TermDocs termDocs=reader.termDocs(term);
//遍历每个文档
while(termDocs.next()){
bits.set(termDocs.doc(),false);
}
retrun bits;
}
}
or
public class MySecurityFilter extends Filter{
public static final int SECURITY=0;
public BitSet bits(IndexReader reader) throws IOException{
//先初始化一个BitSet对象
final BitSet bits=new BitSet(reader.maxDoc());
//将整个集合置为true,表示当前集合内的所有文档都是可以被检索到的
bits.set(0,bits.size()-1);
//构造一个Term对象,代表最高安全级别
Term term=new Term("securitylevel",SECURITY+"");
//初始化一个IndexSearcher对象
//查找securitylevel这个Field的值为SECURITY的文档
IndexSearcher searcher=new IndexSearcher(term);
Hits hits=searcher.search(new TermQuery(term));
for(int i=0;i<hits.length();i++){
bits.set(hits.id(i),false);
}
retrun bits;
}
}
注意:Filter实际上在进行真正的查询之前,已经遍历过一次一遍索引了,因此无
论使用何种Filter,都不应该忽视它对查询效率的影响。
4.在结果中查询(QueryFilter)
在QueryFilter的bits方法中,调用IndexSearcher方法,对注入的Query进行一次
检索,然后在要被返回的BitSet中,将检索结果所对应的文档标记为true,即过滤掉了
所有不再检索结果范围内的文档。
发表评论
-
基于sensei+lucene的分布式搜索终于上线了-2012-12-08
2011-12-08 13:26 1637基于sensei+lucene的分布式搜索终于上线了 ... -
[转载] sensei分布式实时搜索系统源码解析(二) 分布式Search的流程
2011-07-22 14:57 1477看来自己很懒,发现前同事的sensei 研究了 转载: ht ... -
[转载] sensei分布式实时搜索系统源码解析(一) senseiServer的启动及若干概念
2011-07-22 14:55 1785看来自己很懒,发现前同事的sensei 研究了 转载:htt ... -
lucene分布式搜索sensei的使用及完善
2011-07-22 14:32 3550原创文章,转载请注明 ... -
转载:几种常见的基于Lucene的开源搜索解决方案对比
2011-04-06 14:38 1335一 直接使用 Lucene ( http://lucene ... -
转载: Apache Zookeeper入门1
2011-04-06 14:36 1906源: http://www.javabloger.com/ar ... -
转载:Lucene查询语法详解
2011-04-02 10:33 1108英文原文地址:http: ... -
各种字符串Hash函数比较
2011-02-12 14:54 4129Java自带的字符串hash函数: public ... -
Lucene MoreLikeThisQuery 例子 备注
2011-01-06 11:22 14551。 编码问题: MoreLikeThisQuery中的 ... -
Lucene MoreLikeThisQuery 例子
2011-01-04 13:42 2831要做一个跟文章标题相关的新闻,本来想简单做一下,就是把标 ... -
lucene 3.0 分词例子 转载
2010-12-27 17:30 1935源:http://hxraid.iteye.com/blog ... -
[转载] lucene使用与优化
2010-12-03 10:14 1059源:http://www.cnblogs.com/bysshi ... -
[转载] 几种常见的基于Lucene的开源搜索解决方案对比
2010-12-02 16:07 908源:http://blog.fulin.org/201 ... -
lucene中的Token, TokenStream, Tokenizer, Analyzer
2010-11-22 10:41 1353转载: Token: 如果一个字段被token化,这表示它经 ... -
Lucene3.0的几种分词系统
2010-11-17 17:25 12891、 StopAnalyzer StopAnalyze ... -
当前几个主要的Lucene中文分词器的比较
2010-11-17 12:35 13261. 基本介绍: paoding :Lucene中 ... -
lucene score explain 评分解释说明
2010-11-16 17:29 2264通过Searcher.explain(Query qu ... -
lucene 排序 (Sort SortField 构造函数)
2010-11-09 13:58 4119注意: 在lucene2.9中,排序的字段域必须inde ... -
lucene 2010 大会资料 Lucene Revolution 2010
2010-10-27 15:41 956lucene 2010 大会资料资料下载 http://ww ... -
bobo-browse 的分组统计(Faceted Search)
2010-10-25 16:43 2691基于lucene的bobo-browse 的分组统计(Face ...
相关推荐
### 一、Lucene基本概念 1. **索引**:Lucene首先对文本进行索引,将文本内容转换为一系列可搜索的结构。索引过程包括分词(Tokenization)、词干提取(Stemming)、停用词处理(Stop Word Removal)等步骤。 2. *...
### 一、Lucene 基本概念 1. **索引(Index)**:Lucene 的核心功能是建立索引,它将非结构化的文本数据转换成可供快速搜索的数据结构。索引过程包括分词(Tokenization)、词干提取(Stemming)、停用词过滤...
一、Lucene基本概念 Lucene是一个开源的Java库,它提供了一个强大的信息检索API,支持索引和搜索大量文本数据。其核心功能包括文档索引、查询解析、评分机制以及结果排序等。通过Lucene,开发者可以快速地构建出...
1. **Lucene基本概念** - **索引**: Lucene首先需要创建索引,将文本数据转换为可搜索的结构。索引过程包括分析、分词和倒排索引等步骤。 - **分析器**: 分析器负责将输入文本拆分成有意义的单位,即术语(tokens...
### 一、Lucene基本概念 1. **索引(Index)**:Lucene首先将数据转换成索引,这个过程类似于传统书籍的目录。索引包含文档的关键词及其位置信息,使得快速查找和排序变得可能。 2. **文档(Document)**:在...
Lucene基本概念 - **文档(Document)**:在Lucene中,一个文档代表你要索引的信息单元,它可以包含多个字段(Field)。 - **字段(Field)**:字段是文档的组成部分,每个字段都有特定的类型(如文本、日期等)...
1. **Lucene基本概念**:Lucene的核心概念包括文档(Document)、字段(Field)、索引(Index)和查询(Query)。文档是由一系列字段组成的,每个字段有特定的类型(如文本、数字等)。索引是Lucene对这些文档进行...
**一、Lucene基本概念** 1. **索引**:在Lucene中,数据不是直接存储的,而是被转换为一种叫做索引的数据结构。索引是经过分析和分词后的文档内容,使得搜索过程可以快速定位到相关的文档。 2. **文档**:在Lucene...
1. **Lucene基本概念**:了解Lucene的基本架构,如文档、字段、术语(token)、倒排索引等。这些概念构成了Lucene搜索引擎的基础。 2. **索引创建**:学习如何将文本数据转换为可搜索的Lucene索引,包括分词、分析...
### 一、Lucene基本概念 1. **索引(Index)**: Lucene首先将文档内容转换为可搜索的结构化数据,即索引。索引是经过特殊处理的数据结构,允许快速定位到包含特定查询词的文档。 2. **分词(Tokenization)**: ...
Lucene基本概念** - **索引(Indexing)**:Lucene首先对文档进行分析和处理,将其转化为结构化的索引数据。这个过程包括分词(Tokenization)、去除停用词(Stopword Removal)、词干提取(Stemming)等。 - **...
1. **Lucene基本概念** - **全文检索**:Lucene的核心功能是进行全文检索,它能将非结构化的文本数据转换成可搜索的索引。 - **倒排索引**:Lucene采用倒排索引技术,将文档中的词汇与文档ID关联,提高了查询速度...
一、Lucene基本概念 1. 文档(Document):在Lucene中,文档是信息的基本单位,它由多个字段(Field)组成,每个字段有对应的名称和内容。例如,一个网页可以被看作一个文档,其中的标题、正文、URL等可以作为不同...
1. **Lucene基本概念**:理解Lucene的索引结构,如倒排索引,以及其如何提高搜索效率。 2. **数据库集成**:学习如何将MySQL中的数据导入到Lucene的索引中,可能涉及JDBC连接、SQL查询等知识。 3. **索引创建**:...
### 一、Lucene 基本概念 1. **索引(Index)**:搜索引擎的核心是索引,类似于书籍的目录。Lucene 把文档内容转换成倒排索引,使得快速查找匹配的文档变得可能。 2. **文档(Document)**:在 Lucene 中,每个文档...
1. **Lucene基本概念** - **索引**:Lucene的核心是构建索引,它将文本数据转换为倒排索引,以便快速查找包含特定词的文档。 - **文档**:在Lucene中,文档是信息的基本单位,可以包含多个字段,每个字段都有特定...
一、Lucene基本概念 1. 文档(Document):在Lucene中,一个文档代表了要索引的信息源,它可以是网页、电子邮件、PDF文档等。文档由多个字段(Field)组成,每个字段具有不同的含义和处理方式。 2. 字段(Field)...
一、Lucene基本概念与架构 1.1 Lucene核心组件:主要包括索引(Index)、文档(Document)、字段(Field)和分词器(Analyzer)。索引是Lucene的核心,它将文本数据转换成可以高效查询的结构;文档是由多个字段组成...
1. **Lucene基本概念**:Lucene是一个开源的全文检索库,它提供了索引和搜索功能,可以嵌入到各种Java应用程序中。书中首先会介绍什么是全文检索,以及Lucene如何通过倒排索引实现高效搜索。倒排索引是一种将词与...
**一、Lucene基本概念** 1. **索引(Index)**: Lucene首先对文档内容建立索引,类似于图书的目录,以便快速定位到所需信息。索引过程包括分词(Tokenization)、词干提取(Stemming)、停用词处理(Stop Word ...