本文来自: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(); } }
简单记录一下笔记和代码~需要完整教程的可以购买北风网的视频(我可不是打广告喂....