03_Lucene学习笔记
2017-08-30 本文已影响36人
明天你好向前奔跑
1. Lucene入门程序
使用到的jar包:
mysql5.1驱动包:mysql-connector-java-5.1.7-bin.jar
核心包:lucene-core-4.10.3.jar
分词器通用包:lucene-analyzers-common-4.10.3.jar
junit包:junit-4.9.jar
/**
* 创建索引
*/
@Test
public void testIndex() throws IOException {
//第一步. 创建一个IndexWriter对象(反向确定需要的条件)
//1. 指定索引库的存放位置Directory对象
//2. 指定一个分析器,对文档的内容进行分词分析
Directory directory = FSDirectory.open(new File("D:/lucence/index"));
Analyzer analyzer = new StandardAnalyzer();
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
IndexWriter indexWriter = new IndexWriter(directory, config);
//第二步. 获取原数据
File file = new File("D:/searchsource");
File[] files = file.listFiles();
//第三部.遍历原数据,创建field对象,将field对象添加到document文档对象中
for (File f : files) {
//2. 创建document文档对象
Document document = new Document();
//文件名称
String fileName = f.getName();
Field fileNameField = new TextField("fileName", fileName, Field.Store.YES);
//文件大小
long fileSize = FileUtils.sizeOf(f);
Field fileSizeField = new LongField("fileSize", fileSize, Field.Store.YES);
//文件位置
String path = f.getPath();
String absolutePath = f.getAbsolutePath();
Field fieldPathField = new StoredField("filePath", path);
//文件内容
String fileContent = FileUtils.readFileToString(f);
Field fileContentField = new TextField("fileContent", fileContent, Field.Store.YES);
//将各个Field,添加到document对象中
document.add(fileNameField);
document.add(fileSizeField);
document.add(fieldPathField);
document.add(fileContentField);
//4. 使用IndexWriter对象将document对象写入索引库,此过程中进行索引创建。并将索引与document对象写入索引库
indexWriter.addDocument(document);
}
//5. 关闭IndexWriter对象
indexWriter.close();
}
@Test
//搜索索引
public void testQuery() throws IOException {
try {
// 第一步:创建一个Directory对象,也就是索引库存放的位置D:\lucence\index
Directory directory = FSDirectory.open(new File("D:/lucence/index"));//磁盘
// 第二步:创建一个indexReader对象,需要指定Directory对象。
IndexReader indexReader = DirectoryReader.open(directory);
// 第三步:创建一个indexsearcher对象,需要指定IndexReader对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
// 第四步:创建一个TermQuery对象,指定查询的域和查询的关键词。
Query query = new TermQuery(new Term("fileName", "web"));
// 第五步:执行查询。参数1:查询对象,参数2:查询条数
TopDocs topDocs = indexSearcher.search(query, 10);
// 第六步:返回查询结果。遍历查询结果并输出。
ScoreDoc[] docs = topDocs.scoreDocs;
System.out.println(docs.length);
for (ScoreDoc scoreDoc : docs) {
//查询出来的文件的索引
int doc = scoreDoc.doc;
//根据索引查询索引库,获取文档
Document document = indexSearcher.doc(doc);
//查询索引库存储的文档内容,完成测试
//文件名称
String fileName = document.get("fileName");
System.out.println(fileName);
//文件大小
String fileSize = document.get("fileSize");
System.out.println(fileSize);
//文件位置
String filePath = document.get("filePath");
System.out.println(filePath);
//文件内容
String fileContent = document.get("fileContent");
System.out.println(fileContent);
}
//关闭IndexReader对象
indexReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
2. Field 域
2.1 Field属性
Field是文档中的域,包括Field名和Field值两部分,一个文档可以包括多个Field,
Document只是Field的一个承载体,Field值即为要索引的内容,也是要搜索的内容。
- 是否分词(tokenized)
- 是,将field的内容分成一个一个单词。分词的目的:分词目的为了索引
- 商品的名称,商品的介绍。
- 否,不分词,将内容作为一个整体存储。
- 商品ID 身份证号,图片路径
- 是,将field的内容分成一个一个单词。分词的目的:分词目的为了索引
-
是否索引(indexed)
- 是, 将field的值建立索引,索引的目的:索引的目的为了搜索。
- 商品的名称,商品的介绍
- 否,不建立索引
- 图片路径
- 是, 将field的值建立索引,索引的目的:索引的目的为了搜索。
-
是否存储(stored)
- 是, 存储field的值。存储的目的:(为了展示在页面)
- 商品名称,图片路径
- 否, 不存储field的值。
- 商品介绍。如果需要展示,根据ID从数据库查询展示在详情页面
- 是, 存储field的值。存储的目的:(为了展示在页面)
2.2 Field的常用类型
1.png3. 第三方中文分词器IK-analyzer
Lucene自带的默认分词器不能满足中文分词的需求。
因此使用第三方中文分词器IK-annalyzer.
使用:
IKAnalyzer继承Lucene的Analyzer抽象类,使用IKAnalyzer和Lucene自带的分词器方法一样,将Analyzer测试代码改为IKAnalyzer测试中文分词效果。
可以配置扩展词典和停用词词典。
如果使用中文分词器ik-analyzer,就需要在索引和搜索流程程序中使用一致的分词器ik-analyzer。
1. 添加jar包
2. 拷贝IK-analyzer的三个配置文件
3. 使用即可
配置文件:
IKAnalyzer.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典-->
<entry key="ext_dict">mydict.dic;</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords">ext_stopword.dic</entry>
</properties>
ext.dic: 扩展词汇
高富帅
二维表
stopword.dic:停止词典
我
是
用
的
二
维
表
来
a
an
------------------------------------------
使用:
Analyzer analyzer = new IKAnalyzer();
4. 索引维护
这里我将获取IndexWriter
的方法抽取出来:
private IndexWriter getIndexWriter() throws IOException {
//get index directory
Directory directory = FSDirectory.open(new File("D:/lucence/index3"));
//get analyzer
//Analyzer analyzer = new StandardAnalyzer();
//获取中文分词器IKAnalyzer
Analyzer analyzer = new IKAnalyzer();
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST,analyzer);
//get indexWriter
return new IndexWriter(directory,config);
}
4.1 添加索引
参考上面入门程序,调用indexWriter.addDocument(document);
4.2 删除所有索引
@Test
public void testDeleteAllIndex() throws IOException {
IndexWriter indexWriter = getIndexWriter();
indexWriter.deleteAll();
indexWriter.close();
}
4.3 删除指定field的索引
@Test
public void testDeleteIndex() throws IOException {
IndexWriter indexWriter = getIndexWriter();
indexWriter.deleteDocuments(new Term("fileName","web"));
indexWriter.close();
}
4.4 更新索引
@Test
public void testUpdateIndex() throws IOException {
IndexWriter indexWriter = getIndexWriter();
//build update document
Document document = new Document();
document.add(new TextField("fileName","testUpdate",Field.Store.YES));
//update
indexWriter.updateDocument(new Term("fileName","welcome"),document);
//close indexWriter
indexWriter.close();
}