标签:
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();
}
}
标签:
原文地址:http://blog.csdn.net/wenniuwuren/article/details/49949033