Document 对表一些 Field 的集合。 可以理解为虚拟文档 - 比如 Web 页面、 Email 信息或者文本文件, 然后可以从中获取大量数据。
三. 代码实战
import java.io.IOException; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.*; import org.apache.lucene.search.*; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.store.RAMDirectory; /** * Lucene 检索内存索引 * * @author wenniuwuren * */ public class LuceneTest { public static void main(String[] args) throws IOException { long startTime = System.currentTimeMillis(); // 新建一个内存目录对象 Directory directory = new RAMDirectory(); //Directory diskDirectory = new FSDirectory(); //使用 IKAnalyzer 进行分词 StandardAnalyzer analyzer = new StandardAnalyzer(); IndexWriterConfig config = new IndexWriterConfig(analyzer); /* * 创建索引写入对象,该对象既可以把索引写入到磁盘中也可以写入到内存中。 参数说明: * directory:目录对象,也可以是FSDirectory 磁盘目录对象 * config:分词器,分词器就是将检索的关键字分割成一组组词组, * 例子是 Lucene 自带的, 也可以使用第三方的分词器。 */ IndexWriter writer = new IndexWriter(directory, config); // 创建Document 文档对象,在lucene中创建的索引可以看成数据库中的一张表, // 表中也可以有字段,往里面添加内容之后可以根据字段去匹配查询 // 下面创建的doc对象中添加了三个字段,分别为name,sex,dosomething Document doc = new Document(); /* * 参数说明 public Field(String name, String value, Store store, Index index) * name : 字段名称 * value : 字段的值 * * store : * Field.Store.YES:存储字段值(未分词前的字段值)可以用 IndexReader 恢复。 对于需要展示搜索结果的一些域很有用(URL、 标题) * Field.Store.NO:不存储,存储与索引没有关系。 通常跟 Index.ANALYZED 选项共同来索引大的文本, 通常这些不需要恢复初始格式, 如 Wbe 页面征文 * Field.Store.COMPRESS:压缩存储,用于长文本或二进制,但性能受损。 CPU 计算时间换空间 * * index : 建立索引的方式,是否建立分词等等 * Field.Index.ANALYZED:分词建索引, 使每个分词可以被索引 * Field.Index.NOT_ANALYZED:不分词但是索引。 适用于不能被分解的值: URL、 社保号等。 尤其适用于精确搜索。 * Field.Index.ANALYZED_NO_NORMS:分词建索引,不在索引中存储 norms 信息。 norms 记录了索引中的 index-time boost 信息, 搜索时比较耗费内存 * Field.Index.NOT_ANALYZED_NO_NORMS:与 Field.Index.NOT_ANALYZED 相似, 但也不存储 norms(加权基准)。通常用于搜索期间节省索引空间和减少内存耗费。 * Field.Index.NO -- 使对应的值不能被搜索 */ doc.add(new Field("name", "wenniuwuren", Field.Store.YES,Field.Index.ANALYZED)); doc.add(new Field("sex", "男性", Field.Store.YES,Field.Index.NOT_ANALYZED)); doc.add(new Field("dosometing", "I am learning lucene ",Field.Store.YES, Field.Index.ANALYZED)); // 文档对象加入索引 writer.addDocument(doc); writer.close(); // 这里可以提前关闭,因为dictory 写入内存之后 与IndexWriter 没有任何关系了 // 因为索引放在内存中,所以存放进去之后要立马测试,否则,关闭应用程序之后就检索不到了 // 创建IndexSearcher 检索索引的对象,里面要传递上面写入的内存目录对象directory // 打开索引文件 磁盘方式FSDirectory.open(new File()); IndexReader 开销较大, 建议搜友搜索期间使用同一个 IndexReader reader = DirectoryReader.open(directory); IndexSearcher searcher = new IndexSearcher(reader); // TermQuery 最基本的 Query 实现, 解析查询字符串 Query query = new TermQuery(new Term("dosometing", "lucene")); // Query query = new TermQuery(new Term("sex", "男")); // 未分词, 搜索不到 // Query query = new TermQuery(new Term("name", "wen")); // 虽然分词了, 但是英文需要空格隔开才算一个分词, 搜索不到 // 去索引目录中查询,返回的是 TopDocs 对象,里面存放的就是上面放的 document 文档对象的前(TOP)几个内容 TopDocs result = searcher.search(query, 10); long endTime = System.currentTimeMillis(); System.out.println("总共花费" + (endTime - startTime) + "毫秒,检索到" + result.totalHits + "条记录。"); for (int i = 0; i < result.scoreDocs.length; i++) { Document document = searcher.doc(result.scoreDocs[i].doc); System.out.println("name:" + document.getField("name").stringValue()); System.out.println("sex:" + document.getField("sex").stringValue()); System.out.println("dosomething:" + document.getField("dosometing").stringValue()); // 对搜索结果评分细节 Explanation explanation = searcher.explain(query, result.scoreDocs[i].doc); System.out.println(explanation.toString()); } writer.close(); directory.close(); } }