More Related Content Similar to Lucene2 4学习笔记1 Similar to Lucene2 4学习笔记1 (20) Lucene2 4学习笔记11. lucene2.4 学习笔记 1-( 初学 Lucene, 简单例子 )
关键字: indexwriter hits lucene field
说明一下,这一篇文章的用到的 lucene,是用 2.4 版本的,主要在查询的时候 2.0
版本的 lucene 与以前的版本有了一些区别
下面是一个简单的例子
1.第一步建立索引
Java 代码
1. public class IndexDatebase {
2.
3. public static void main(String[] args) throws IOException {
4. //创建保存索引的目录
5. String indexDir = "d://indexDir";
6. //创建 Directory 对象,具体的实现有
FSDirectory,RAMDirectory,MMapDirectory,NIOFSDirector
7. //FSDirectory 表示索引是放到文件里面的,RAMDirectory 是放
到内存里面
8. //new RAMDirectory()
9. Directory index = FSDirectory.getDirectory(new File(ind
exDir));
10. //创建索引 IndexWriter 对象,要四个参数,第一个是
Directory 对象,可以传 File 和 String 类型的 path
11. //new StandardAnalyzer()这个表示分析器,拆字用的,其它的
分析器还有 new ChineseAnalyzer(),new IK_CAnalyzer(),new CJKAnal
yzer()
12. //第三个参数代表是新建 Index 还是在原来上面的追加,true
是新建
13. //表示分词的最大值,比如说 new MaxFieldLength(2),就表
示两个字一分,一般用 IndexWriter.MaxFieldLength.LIMITED
14. IndexWriter writer = new IndexWriter(indexDir,new Stand
ardAnalyzer(),true,IndexWriter.MaxFieldLength.LIMITED);
15. //IndexWriter writer = new IndexWriter(indexDir,new Sta
ndardAnalyzer(),true,new MaxFieldLength(20));
16. addDoc(writer,"法医鉴定称湖北石南海首死亡厨师系自杀");
17. addDoc(writer,"国务院建议珠海横琴岛划南海地交澳门管理");
18. addDoc(writer,"印尼在南海扣 75 名中国渔民 中方要求尽快释
放南海南海南海南海南海南海南海");
19. addDoc(writer,"南海南海南海南海南海南海南海南海南海印尼
在南海扣 75 南海南海名中国渔民 中方要求尽快释放");
2. 20. addDoc(writer,"湖北洪湖一初南海中生被同学刺亡 亲属怒砸
学校 ");
21. //优化
22. writer.optimize();
23. //关闭流
24. writer.close();
25.
26. }
27. /**
28. * 把 Document 对象加到 Index 里面
29. * @param w
30. * @param value
31. * @throws IOException
32. */
33. private static void addDoc(IndexWriter w, String value) thr
ows IOException {
34. //新建的 Document 对象
35. Document doc = new Document();
36. //Field(String name, String value, Store store, Index i
ndex)表示保存,并建立索引,如果字段多的话,不要都建立索引
37. doc.add(new Field("title", value, Field.Store.YES,Field
.Index.ANALYZED));
38. //加进去
39. w.addDocument(doc);
40. }
41.}
2.从索引中找出相应的对象
Java 代码
1. public class QueryLucene {
2.
3. public static void main(String[] args) throws ParseExceptio
n, CorruptIndexException, IOException {
4. //创建 Query,QueryParser 对象,根据 Field 建立的索引的
KEY 来搜,并设置要搜的内容
5. Query query = new QueryParser("title",new StandardAnaly
zer()).parse("南海");
6. //可以理解成读 Index 对象,Directory,File,String 都行
7. IndexSearcher indexSearch = new IndexSearcher(FSDirecto
ry.getDirectory(new File("d://indexDir")));
8. //表示查出前四个
9. TopDocCollector collector = new TopDocCollector(4);
3. 10. //查找
11. indexSearch.search(query,collector);
12. //ScoreDoc 这个对象还不清楚,但是有多少结果,就有多少个
这个对象
13. ScoreDoc[] hits = collector.topDocs().scoreDocs;
14. for(int i=0;i<hits.length;++i) {
15. //找到这个 Document 原来的索引值
16. int docId = hits[i].doc;
17. System.out.println(docId);
18. //根据这个值找到对象的 Document
19. Document d = indexSearch.doc(docId);
20. System.out.println((i + 1) + ". " + d.get("title"))
;
21. }
22.
23. }
24.
25.}
1.x,2.0 和 2.4 是有一些区别的
比如说:
1
Java 代码
1. //1.x
2. IndexWriter writer = new IndexWriter(indexPath, getAnalyzer(),
true);
3. //2.0,2.4
4. IndexWriter writer = new IndexWriter(indexPath, getAnalyzer(),
true, IndexWriter.MaxFieldLength.UNLIMITED);
2.
Java 代码
1. Field.Index.TOKENIZED 替换为 Field.Index.ANALYZED
2. 没啥特殊的,改了一个名字而已
3.
Java 代码
4. 1. IndexWriter.flush();
2. 替换为
3. IndexWriter.commit();
4.org.apache.lucene.search.Hits;
这个类将在 3.0 中被删除
新的使用方法在上面的例子中
5.Field 的创建
Java 代码
1. 在 2.0+中
2. Field 没了 Keyword、UnIndexed、UnStored、Text 这几个静态成员,只能用
3. Field(String, String, Store, Index)。
4. Keyword 对应 Field.Store.YES, Field.Index.UN_TOKENIZED,
5. UnIndexed 对应 Field.Store.YES, Field.Index.NO,
6. UnStored 对应 Field.Store.NO, Field.Index.TOKENIZED,
7. Text 对应 Field.Store.YES, Field.Index.TOKENIZED
8. //2.0 版本以上
9. Field(String name, byte[] value, Field.Store store)
10. // Create a stored field with binary value.
11.Field(String name, Reader reader)
12. // Create a tokenized and indexed field that is not s
tored.
13.Field(String name, Reader reader, Field.TermVector termVector)
14. // Create a tokenized and indexed field that is not s
tored, optionally with storing term vectors.
15.Field(String name, String value, Field.Store store, Field.Index
index)
16. // Create a field by specifying its name, value and h
ow it will be saved in the index.
17.Field(String name, String value, Field.Store store, Field.Index
index, Field.TermVector termVector)
18. // Create a field by specifying its name, value and h
ow it will be saved in the index.
Field.Store 表示“是否存储”,即该 Field 内的信息是否要被原封不动的保
存在索引中。
5. Field.Index 表示“是否索引”,即在这个 Field 中的数据是否在将来检索时
需要被用户检索到,一个“不索引”的 Field 通常仅是提供辅助信息储存的功
能。
Field.TermVector 表示“是否切词”,即在这个 Field 中的数据是否需要被切
词。
通常,参数用 Reader,表示在文本流数据源中获取数据,数据量一般会比较大。
像链接地址 URL、文件系统路径信息、 时间日期、人名、 居民身份证、 电话号码等等
通常将被索引并且完整的存储在索引中,但一般不需要切分词,通常用上面的
第四个构造函数,第三四个参数分别为 Field.Store.YES, Field.Index.YES。
而长文本通常可用第 3 个构造函数。
IndexSearch 类 查询器
搜索入口,继承自 Search
1.public IndexSearcher(Directory directory)
使用方法
String IndexPath="D:/IndexPath";
Directory directory=FSDirectory.getDirectory(IndexPath);
IndexSearcher searcher=new IndexSearcher(directory);
支持 RAM 存储的索引,提高检索速度,建议使用,因为此方法将索引存放的路径与搜索分离
2.public IndexSearcher(String path)
直接操作索引目录.不支持 RAM 存储的索引
IndexSearcher searcher=new IndexSearcher("D:/IndexPath");
3.public IndexSearcher(IndexReader r)
IndexSearcher searcher=IndexSearcher(reader);
4.private IndexSearcher(IndexReader r, boolean closeReader)
在 3 的 基 础 上 对 了 判 断 在 关 闭 IndexSearcher 时 是 否 要 关 闭 所 带 的 IndexReader 对 象 的
boolean 类型参数
多索引目录就是要在多个索引目录的中进行比较搜索,类似概念在 SQL 中就是 select *
from TableA union select * from TableB。
IndexSearcher[] searchers = new IndexSearcher[2];
searchers[0] = new IndexSearcher(IndexPath0);
searchers[1] = new IndexSearcher(IndexPath1);
IndexSearcher 类的主要方法 Search 通过重载实现多种检索方式.通过其参数控制检索.
参数解释
Weigth weigth 权重 指定索引中文档重要性参数,改变默认其值
6. HitCollector results 保存搜索的所有结果.
Filter filter 指定对结果进行过滤的方式
Query query 每个 Search 必须的对象参数.指定检索的方式
Sort sort 指定检索排序的方法.可自定义排序方式进行结果的排序和输出
Query 有很多的子类 指定了不同的查询方式,query 是用户输入的内容,analyzer 是用来将用
户输入的内容也作分析处理
TermQuery
Term t=new Term(”contents”,”lucene”); 构造 TermQuery 把查询条件视为一个 key, 要求和查询
内容完全匹配,比如 Field.Keyword 类型就可以使用 TermQuery
RangeQuery 区间检索
RangeQuery 表 示 一 个 范 围 的 搜 索 条 件 , 在 年 龄 , 日 期 , 工 资 等 数 字 类 的 索 引 库 中 常 用
R,angeQuery query = new RangeQuery(begin, end, included); 类似 sql 中 betwee...and..... 最后一
个 boolean 值表示是否包含边界条件本身 , 用字符表示为”[begin TO end]” 或者”{begin TO
end}”
PrefixQuery 字符串前缀检索,如"sys*"
BooleanQuery 逻辑组合检索
组合的 Query,你可以把各种 Query 添加进去并标明他们的逻辑关系,添加条件用 public void
add(Query query, boolean required, boolean prohibited) 方 法 , 后 两 个 boolean 变 量 是
标示 AND OR NOT 三种关系 字符表示为” AND OR NOT” 或 “+ -” ,一个 BooleanQuery
中可以添加多个 Query, 如果超过 setMaxClauseCount(int) 的值 ( 默认 1024 个 ) 的话 , 会抛出
TooManyClauses 错误.
PhraseQuery 短语检索
PhraseQuery 所以提供了一个 setSlop()参数,在查询中 ,lucene 会尝试调整单词的距离和位置 ,
这个参数表示可以接受调整次数限制,如果实际的内容可以在这么多步内调整为完全匹配,那
么就被视为匹配 . 在默认情况下 slop 的值是 0, 所以默认是不支持非严格匹配的 , 通过设置
slop 参数(比如”red pig”匹配”red fat pig”就需要 1 个 slop 来把 pig 后移动 1 位),我们可以让
lucene 来模糊查询. 值得注意的是,PhraseQuery 不保证前后单词的次序 ,在上面的例子中,”pig
red”需要 2 个 slop,也就是如果 slop 如果大于等于 2,那么”pig red”也会被认为是匹配的.
WildcardQuery 通配符检索
使用?和*来表示一个或多个字母比如 sys*可以匹配 system ,systop,systaltic…,
FuzzyQuery 模糊搜索
一般不处理中文,处理于英文的各种时态变化和复数形式,匹配结果的相关度是不一样的.
QueryParser 使用
QueryParser 将用户输入转为 Query 或者 Query 组, 将 Query 的字符表示(Query.toString)转化
为实际的 Query 对象,
Hit 搜索结果的处理:Hits 对象
7. Hits 对象是搜索结果的集合 主要有下面几个方法
1.length() , 记录有多少条结果返回
2.doc(n) 返回第 n 个记录
3.id(in) 返回第 n 个记录的 Document ID
4.score(n) 第 n 个记录的相关度(积分)
本 文 来 自 CSDN 博 客 , 转 载 请 标 明 出 处 :
http://blog.csdn.net/lwlsoftware/archive/2009/02/21/3916082.aspx