作者:lighter, 江南白衣
Lucene是apache组织的一个用java实现全文搜索引擎的开源项目。其功能非常的强大,但api其实很简单的,它最主要就是做两件事:建立索引和进行搜索。
lucene建立索引的过程就是将待索引的对象转化为Lucene的Document对象,使用IndexWriter将其写入lucene 自定义格式的索引文件中。
待索引的对象可以来自文件、数据库等任意途径,用户自行编码遍历目录读取文件或者查询数据库表取得ResultSet,Lucene的API只负责和字符串打交道。
从源代码中,可以看出Field 构造函数如下:
Field(String name, byte[] value, Field.Store store) Field(String name, Reader reader) Field(String name, Reader reader, Field.TermVector termVector) Field(String name, String value, Field.Store store, Field.Index index) Field(String name, String value, Field.Store store, Field.Index index, Field.TermVector termVector)
在Field当中有三个内部类:Field.Index,Field.Store,Field.termVector。其中
上面所说的Field属性与lucene1.4.3版本的有比较大的不同,在旧版的1.4.3里lucene是通过Field.Keyword(...),FieldUnIndexed(...),FieldUnstored(...)和Field.Text(...)来设置不同字段的类型以达到不同的用途,而当前版本由Field.Index和Field.Store两个字段的不同组合来达到上述效果。
还有一点说明,其中的两个构造函数其默认的值为Field.Store.NO和Field.Index.TOKENIZED。:
Field(String name, Reader reader) Field(String name, Reader reader, Field.TermVector termVector)
IndexReader reader = IndexReader.open("C:\\springside"); reader.deleteDocument(X); //这里的X是一个int的常数;不推荐这一种删除方法 reader.deleteDocument(new Term("name","springside"));//这是另一种删除索引的方法,按字段来删除,推荐使用这一种做法 reader.close();
length(): 返回搜索结果的总数,下面简单的用法中有用到Hit的这一个方法 doc(int n): 返回第n个文档 iterator(): 返回一个迭代器
这里再提一下Hits,这也是Lucene比较精彩的地方,熟悉hibernate的朋友都知道hibernate有一个延迟加载的属性,同样,Lucene也有。Hits对象也是采用延迟加载的方式返回结果的,当要访问某个文档时,Hits对象就在内部对Lucene的索引又进行一次检索,最后才将结果返回到页面显示。
首先把lucene的包放在classpath路径中去,写下面一个简单的类:
public class FSDirectoryTest { //建立索引的路径 public static final String path = "c:\\index2"; public static void main(String[] args) throws Exception { Document doc1 = new Document(); doc1.add( new Field("name", "lighter springside com",Field.Store.YES,Field.Index.TOKENIZED)); Document doc2 = new Document(); doc2.add(new Field("name", "lighter blog",Field.Store.YES,Field.Index.TOKENIZED)); IndexWriter writer = new IndexWriter(FSDirectory.getDirectory(path, true), new StandardAnalyzer(), true); writer.addDocument(doc1); writer.addDocument(doc2); writer.close(); IndexSearcher searcher = new IndexSearcher(path); Hits hits = null; Query query = null; QueryParser qp = new QueryParser("name",new StandardAnalyzer()); query = qp.parse("lighter"); hits = searcher.search(query); System.out.println("查找\"lighter\" 共" + hits.length() + "个结果"); query = qp.parse("springside"); hits = searcher.search(query); System.out.println("查找\"springside\" 共" + hits.length() + "个结果"); } }
执行的结果:
查找"lighter" 共2个结果 查找"springside" 共1个结果
springside社区 更大进步,吸引更多用户,更多贡献 2007年
而"2.txt"和"3.txt"的内容也可以随便写几写,这里懒写,就复制一个和1.txt文件的内容一样吧
/** * author lighter date 2006-8-7 */ public class LuceneExample { public static void main(String[] args) throws Exception { File fileDir = new File("c:\\s"); // 指明要索引文件夹的位置,这里是C盘的S文件夹下 File indexDir = new File("c:\\index"); // 这里放索引文件的位置 File[] textFiles = fileDir.listFiles(); Analyzer luceneAnalyzer = new StandardAnalyzer(); IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true); indexFile(luceneAnalyzer,indexWriter, textFiles); indexWriter.optimize();//optimize()方法是对索引进行优化 indexWriter.close(); } public static void indexFile(Analyzer luceneAnalyzer,IndexWriter indexWriter,File[] textFiles) throws Exception { //增加document到索引去 for (int i = 0; i < textFiles.length; i++) { if (textFiles[i].isFile() && textFiles[i].getName().endsWith(".txt")) { String temp = FileReaderAll(textFiles[i].getCanonicalPath(),"GBK"); Document document = new Document(); Field FieldBody = new Field("body", temp, Field.Store.YES,Field.Index.TOKENIZED); document.add(FieldBody); indexWriter.addDocument(document); } } } public static String FileReaderAll(String FileName, String charset)throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader( new FileInputStream(FileName), charset)); String line = ""; String temp = ""; while ((line = reader.readLine()) != null) { temp += line; } reader.close(); return temp; } }
public class TestQuery { public static void main(String[] args) throws IOException, ParseException { Hits hits = null; String queryString = "社区"; Query query = null; IndexSearcher searcher = new IndexSearcher("c:\\index"); Analyzer analyzer = new StandardAnalyzer(); try { QueryParser qp = new QueryParser("body", analyzer); query = qp.parse(queryString); } catch (ParseException e) { } if (searcher != null) { hits = searcher.search(query); if (hits.length() > 0) { System.out.println("找到:" + hits.length() + " 个结果!"); } } } }
找到:3 个结果!
参考这一篇文章,里面讲得很详细
http://wiki.redsaga.com/confluence/display/HART/Hibernate+Lucene+Integration