本文来自:fair-jm.iteye.com 转截请注明出处
学习的材料是北风网的课程:
http://www.ibeifeng.com/goods-378.html
代码是边看视频边自己码的 不知道是否侵权 如有侵权请告知 会立即删除
lucene的版本更新也挺快的 这套视频我刚买的时候还是4.6.0 昨天看到lucene那已经到4.7.2了
于是用4.7.2做为学习的版本
索引的建立和读取
主要是两个类
IndexWriter和IndexReader
最初的demo也是根据这两个类展开
IndexWriter的构造方法如下:
Constructs a new IndexWriter per the settings given in conf.
需要一个Directory和IndexWriterConfig对象作为参数
其中Directory表示索引存放的路径
IndexWriter包含使用lucene版本(lucene各版本不兼容)和Analyzer(分词器)
代码如下:
//使用标准分词器
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_47);
//使用FSDirectory的open方法打开磁盘上的目录
Directory dir = FSDirectory.open(indexPath.toFile());
//设置IndexWriterConfig
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_47,
analyzer);
得到IndexWriter 需要写入Document对象 Document对象内有很多的Field
也就是将Field填入Document对象 再由IndexWriter写入到磁盘内
代码如下:
try (IndexWriter iw = new IndexWriter(dir, config)) {
Document doc = new Document();
// id:1 title:key1 key2 content:key3 key4
// StringField不分词 查询时要输入完整的查询 例如输入 key1 就不会得到结果
// TextField是分词的 查询词输入 key3或者key4会得到结果 但是输入key3 key4就不会得到结果了
IndexableField idField = new IntField("id", 1, Field.Store.YES);
IndexableField titleField = new StringField("title",
"key1 key2", Field.Store.YES);
IndexableField contentField = new TextField("content",
"key3 key4", Field.Store.YES);
doc.add(idField);
doc.add(titleField);
doc.add(contentField);
iw.addDocument(doc);
iw.commit();
}
} catch (IOException e) {
e.printStackTrace();
}
简单的索引建立就完成了(以上代码花括号不配对是中间截了一下 try没截取 代码中的try是try-with-resources)
然后是通过索引获取内容
需要IndexReader对象 可以通过DirectoryRedaer.open方法得到(传入的参数是放索引的目录)
然后通过IndexSearch传入Query对象参数进行查询 查询得到TopDocs的对象 再进一步得到document的id
将id传入IndexReader的document方法后获得具体的Document对象(好绕啊有没有.....)
最后通过Document对象的get方法传入key 得到value(我所说的key就是上面代码中IndexabelField的第一个 参数)
看具体代码:
public static void searcherDemo(Path indexPath) {
try {
Directory dir = FSDirectory.open(indexPath.toFile());
try (IndexReader reader = DirectoryReader.open(dir)) {
IndexSearcher search = new IndexSearcher(reader);
Query query = new TermQuery(new Term("content", "key3 key4")); //这样查询不到 因为TextField是进行分词的
// Query query = NumericRangeQuery.newIntRange("id", 1, 1, true,true);
TopDocs topDocs = search.search(query, 10);
int hits = topDocs.totalHits;
System.out.println("hits:" + hits);
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc sd : scoreDocs) {
int docId = sd.doc;
Document doc = reader.document(docId);
System.out.println(doc.get("id") + ":" + doc.get("title")
+ ":" + doc.get("content"));
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
简单记录一下笔记和代码~需要完整教程的可以购买北风网的视频(我可不是打广告喂....