lucene学习笔记 高级篇

一、环境
需要导入 lucene.jar 包(在 lucene.apache.org 下载)
二、基本概念
1 Lucene 的工作流程:
(1)  使用 IndexWriter ,在指定的目录建立索引的文件
  (2) 
将需要检索的数据转换位 Document Filed 对象,然后将 Document IndexWriter 添加倒索引的文件中
   (3) 
处理索引信息,关闭 IndexWriter
   (4) 
创建搜索的 Query
   (5) 
IndexSearcher
2 Lucene 的字段类型
Lucene 有四种不同的字段类型: Keyword UnIndexed UnStored Text ,用于指定建立最佳索引。
?        Keyword
字段是指不需要分析器 解析但需要被编入索引并保存到索引中的部分。 JavaSourceCodeIndexer 类使用该字段来保存导入类的声明。
?        UnIndexed
字段是既不被分析也不被索引,但是要被逐字逐句的将其值保存到索引中。由于我们一般要存储文件的位置但又很少用文件名作为关键字来搜索,所以用该字段来索引 Java 文件名。
?        UnStored
字段和 UnIndexed 字段相反。该类型的 Field 要被分析并编入索引,但其值不会被保存到索引中。由于存储方法的全部源代码需要大量的空间。所以用 UnStored 字段来存储被索引的方法源代码。可以直接从 Java 源文件中取出方法的源代码,这样作可以控制我们的索引的大小。
?        Text
字段在索引过程中是要被分析、索引并保存的。类名是作为 Text 字段来保存。下表展示了 JavaSourceCodeIndexer 类使用 Field 字段的一般情况。
 
3 基本概念(与传统表的对比):
Lucene
传统表
说明
IndexWriter
table
 
Document
一条记录
 
Field
每个字段
分为可被索引的,可切分的,不可被切分的,不可被索引的几种组合类型
Hits
RecoreSet
结果集
 
IndexWriter 提供了一些参数可供设置,列表如下
 
属性
默认值
说明
mergeFactor
org.apache.lucene.mergeFactor
10
控制 index 的大小和频率 , 两个作用
1. 一个段有多少 document
2. 多少个段合成一个大段
maxMergeDocs
org.apache.lucene.maxMergeDocs
Integer.MAX_VALUE
限制一个段中的 document 数目
minMergeDocs
org.apache.lucene.minMergeDocs
10
缓存在内存中的 document 数目,超过他以后会写入到磁盘
maxFieldLength
 
1000
一个 Field 中最大 Term 数目,超过部分忽略,不会 index field 中,所以自然也就搜索不到
这些参数的的详细说明比较复杂: mergeFactor 有双重作用
(1) 设置每 mergeFactor document 写入一个段,比如每 10 document 写入一个段
(2) 设置每 mergeFacotr 个小段合并到一个大段,比如 10 document 的时候合并为 1 小段,以后有 10 个小段以后合并到一个大段,有 10 个大段以后再合并,实际的 document 数目会是 mergeFactor 的指数
简单的来说 mergeFactor 越大,系统会用更多的内存,更少磁盘处理,如果要打批量的作 index ,那么把 mergeFactor 设置大没错, mergeFactor 小了以后, index 数目也会增多, searhing 的效率会降低, 但是 mergeFactor 增大一点一点,内存消耗会增大很多 ( 指数关系 ), 所以要留意不要” out of memory”
maxMergeDocs 设置小,可以强制让达到一定数量的 document 写为一个段,这样可以抵消部分 mergeFactor 的作用 .
minMergeDocs
相当于设置一个小的 cache, 第一个这个数目的 document 会留在内存里面,不写入磁盘。这些参数同样是没有最佳值的, 必须根据实际情况一点点调整。
maxFieldLength
可以在任何时刻设置, 设置后,接下来的 index Field 会按照新的 length 截取,之前已经 index 的部分不会改变。可以设置为 Integer.MAX_VALUE
 
4 几种查询方式       
查询方式
说明
TermQuery
条件查询
例如: TermQuery tquery=new TermQuery(new Term("name","jerry"));
name: 字段名
jerry: 要搜索的字符串
MultiTermQuery
多个字段进行同一关键字的查询
Query query= null;
Query =MultiFieldQueryParser.parse(" ",new String[] {"title","content"},analyzer);
Searcher searcher=new IndexSearcher(indexFilePath);
 Hits hits=searcher.search(query);
BooleanQuery
例如: 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);
WildcardQuery
语义查询(通配符查询)
例: Query query= new WildcardQuery(new Term("sender","*davy*"));
PhraseQuery
短语查询
PrefixQuery
前缀查询
PhrasePrefixQuery
短语前缀查询
FuzzyQuery
模糊查询
RangeQuery
范围查询
SpanQuery
范围查询
在全文检索时建议大家先采用语义时的搜索,先搜索出有意义的内容,之后再进行模糊之类的搜索
(1) 联合两个索引查询,已解决:
IndexSearcher[] searchers = new IndexSearcher[2]; 
  
searchers[0] = new IndexSearcher(m_indexpath);
searchers[1] = new IndexSearcher(m_outindexpath);

MultiSearcher multiSearcher = new MultiSearcher(searchers);

(2)
还有个进行多条件搜索 and or 的操作————
MultiFieldQueryParser
建议重新封装
MultiFieldQueryParser.Parser(p[],d[],f[],analyer)  
or and 操作合一
或者
BooleanQuery m_BooleanQuery = new BooleanQuery();
Query query = QueryParser.Parse(m_SearchText, "INSTRUMENT_NAME", analyzer);
Query query2 = QueryParser.Parse(m_SearchText2, "INSTRUMENT_NAME2", analyzer);
m_BooleanQuery.Add(query, true, false);
m_BooleanQuery.Add(query2, true, false);
(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"));
}
 
5. 为查询优化索引 (index)
Indexwriter.optimize() 方法可以为查询优化索引( index ),之前提到的参数调优是为 indexing 过程本身优化,而这里是为查询优化,优化主要是减少 index 文件数,这样让查询的时候少打开文件,优化过程中, lucene 会拷贝旧的 index 再合并,合并完成以后删除旧的 index ,所以在此期间,磁盘占用增加, IO 符合也会增加,在优化完成瞬间,磁盘占用会是优化前的 2 , optimize 过程中可以同时作 search
 
 
 
4.org.apache.lucene.document.Field
        
即上文所说的“字段”,它是 Document 的片段 section
        Field 的构造函数:
       Field(String name, String string, boolean store, boolean index, boolean token)
        Indexed :如果字段是 Indexed 的,表示这个字段是可检索的。
        Stored :如果字段是 Stored 的,表示这个字段的值可以从检索结果中得到。
        Tokenized :如果一个字段是 Tokenized 的,表示它是有经过 Analyzer 转变后成为一个 tokens 序列,在这个转变过程 tokenization 中,  Analyzer 提取出需要进行索引的文本,而剔除一些冗余的词句(例如: a the,they 等,详见  org.apache.lucene.analysis.StopAnalyzer.ENGLISH_STOP_WORDS  org.apache.lucene.analysis.standard.StandardAnalyzer(String[] stopWords) API )。 Token 是索引时候的 .
 
类型
Analyzed
Indexed
Stored
说明
Field.Keyword(String,String/Date)
N
Y
Y
这个 Field 用来储存会直接用来检索的比如 ( 编号 , 姓名 , 日期等 )
Field.UnIndexed(String,String)
N
N
Y
不会用来检索的信息 , 但是检索后需要显示的 , 比如 , 硬件序列号 , 文档的 url 地址
Field.UnStored(String,String)
Y
Y
N
大段文本内容 , 会用来检索 , 但是检索后不需要从 index 中取内容 , 可以根据 url load 真实的内容
Field.Text(String,String)
Y
Y
Y
检索 , 获取都需要的内容 , 直接放 index , 不过这样会增大 index
Field.Text(String,Reader)
Y
Y
N
如果是一个 Reader, lucene 猜测内容比较多 , 会采用 Unstored 的策略 .
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值