lucene索引库的维护
一、常用的域 field 的使用
1). 关键名词
- 是否分析:是否对域的内容进行分词处理。前提是我们要对域的内容进行查询。
- 是否索引:将Field分析后的词或整个Field值进行索引,只有索引方可搜索到。比如:商品名称、商品简介分析后进行索引,订单号、身份证号不用分析但也要索引,这些将来都要作为查询条件。
- 是否存储:将Field值存储在文档中,存储在文档中的Field才可以从Document中获取,比如:商品名称、订单号,凡是将来要从Document中获取的Field都要存储。
是否存储的标准:是否要将内容展示给用户
2). 各个域的比较
Field类 | 数据类型 | Analyzed是否分析 | Indexed是否索引 | Stored是否存储 | 说明 |
---|---|---|---|---|---|
StringField(FieldName, FieldValue,Store.YES或者Store.NO)) | 字符串 | N | Y | Y或N | 这个Field用来构建一个字符串Field,但是不会进行分析,会将整个串存储在索引中,比如(订单号,姓名等),是否存储在文档中用Store.YES或Store.NO决定 |
LongPoint(String name, long... point) | Long型 | Y | Y | N | 可以使用LongPoint、IntPoint等类型存储数值类型的数据。让数值类型可以进行索引。但是不能存储数据,如果想存储数据还需要使用StoredField。 |
StoredField(FieldName, FieldValue) | 重载方法,支持多种类型 | N | N | Y | 这个Field用来构建不同类型Field,不分析,不索引,但要Field存储在文档中 |
TextField(FieldName, FieldValue, Store.YES或者Store.NO)或TextField(FieldName, reader) | 字符串 或 流 | Y | Y | Y或N | 如果是一个Reader, lucene猜测内容比较多,会采用Unstored的策略. |
二、添加文档
添加文档和创建索引库的步骤如出一辙,注意:不同的文档是可以有不同的域的! 存储不存储是不影响查询的
// 创建一个IndexWriter对象,需要使用IKAnalyzer作为分析器
IndexWriter indexWriter = new IndexWriter(
FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath()),
new IndexWriterConfig(new IKAnalyzer()));
// 读取磁盘上需要添加的文件
File file = new File("F:\\03Web开发\\03_lucene\\02.参考资料\\searchsource\\spring.txt");
// 创建一个Docunment对象
Document document = new Document();
// 向document中添加域
document.add(new TextField("filename", file.getName(), Field.Store.YES));
document.add(new TextField("contect", FileUtils.readFileToString(file, "utf-8"), Field.Store.YES));
document.add(new StoredField("size", FileUtils.sizeOf(file)));
// 将文档写入索引库
indexWriter.addDocument(document);
// 关闭索引库
indexWriter.close();
三、删除索引库
1). 删除所有文档对象 Document
// 创建一个IndexWriter对象,这里使用IKAnalyzer作为分析器
IndexWriter indexWriter = new IndexWriter(
FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath()),
new IndexWriterConfig(new IKAnalyzer()));
// 删除全部文档
indexWriter.deleteAll();
// 关闭索引库
indexWriter.close();
2). 根据查询针对性删除文档对象 Document
IndexWriter indexWriter = new IndexWriter(
FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath()),
new IndexWriterConfig(new IKAnalyzer()));
// 将name域中包含有 php 的文档对象Document删除
indexWriter.deleteDocuments(new Term("name", "php"));
indexWriter.close();
四、更新索引库
更新的原理是 先删除 后添加
IndexWriter indexWriter = new IndexWriter(
FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath()),
new IndexWriterConfig(new IKAnalyzer()));
// 创建一个新的文档用于替换被查询的文档集合
Document document = new Document();
// 向文档中添加域
document.add(new TextField("name", "filename", Field.Store.YES));
document.add(new TextField("context", "file content", Field.Store.YES));
// 更新替换操作
// 第一个为查询被替换的文档集合,第二个参数为一个文档
indexWriter.updateDocument(new Term("name"), document);
/* 下面的方式的第二个参数可以写一个可迭代的集合
indexWriter.updateDocuments(new Term("name"), documents);
*/
// 关闭索引库
indexWriter.close();
五、索引库的查询
1). TermQuery(Query的子类)
根据关键字进行查询,需要执行查询的域以及要查询的关键字
全文检索lucene创建索引库
2). 范围查询(Query的子类)
范围查询,针对 LongPoint 域
//1. 创建一个Director对象,指定索引库的位置
Directory directory = FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath());
//2. 创建一个IndexReader对象
IndexReader indexReader = DirectoryReader.open(directory);
//3. 创建一个IndexSearcher对象,构造方法中的参数indexReader对象。
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//4. 创建一个Query对象,rangeQuery, 第一个为域,第二、三个参数为范围
Query query = LongPoint.newRangeQuery("size", 0L, 100L);
//5. 执行查询,得到一个TopDocs对象
// 参数1: 查询对象; 参数2:限制查询结果返回的最大记录数,
TopDocs topDocs = indexSearcher.search(query, 10);
//6. 取查询结果的总记录数
System.out.println("查询的总记录数:" + topDocs.totalHits);
//7. 取文档列表
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
//8. 打印文档中的内容
for (ScoreDoc doc : scoreDocs) {
// 取文档id
int docId = doc.doc;
// 根据id获取文档对象
Document document = indexSearcher.doc(docId);
System.out.println(document.get("name"));
System.out.println(document.get("path"));
System.out.println(document.get("size"));
System.out.println("--------------------------------");
}
//9. 关闭IndexReader对象。
indexReader.close();
3). QueryParser 进行查询
可以对要查询的内容先分词,然后基于分词的结果进行查询。
- 需要添加一个jar包:
lucene-queryParser-7.4.0.jar
- maven坐标
org.apache.lucene
lucene-queryparser
7.4.0
- 查询示例
//1. 创建一个Director对象,指定索引库的位置
Directory directory = FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath());
//2. 创建一个IndexReader对象
IndexReader indexReader = DirectoryReader.open(directory);
//3. 创建一个IndexSearcher对象,构造方法中的参数indexReader对象。
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//4. 创建一个QueryParser对象,两个参数
// 参数1:默认搜索域,参数2:分析器对象
QueryParser queryParser = new QueryParser("name", new IKAnalyzer());
Query query = queryParser.parse("lucene是一个Java开发的全文检索工具包");
//5. 执行查询,得到一个TopDocs对象
// 参数1: 查询对象; 参数2:限制查询结果返回的最大记录数,
TopDocs topDocs = indexSearcher.search(query, 10);
//6. 取查询结果的总记录数
System.out.println("查询的总记录数:" + topDocs.totalHits);
//7. 取文档列表
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
//8. 打印文档中的内容
for (ScoreDoc doc : scoreDocs) {
// 取文档id
int docId = doc.doc;
// 根据id获取文档对象
Document document = indexSearcher.doc(docId);
System.out.println(document.get("name"));
System.out.println(document.get("path"));
System.out.println(document.get("size"));
System.out.println("--------------------------------");
}
//9. 关闭IndexReader对象。
indexReader.close();