常用索引库操作
是否分析:是否对域的内容进行分词处理。前提是我们要对域的内容进行查询。
是否索引:将Field分析后的词或整个Field值进行索引,只有索引方可搜索到。
是否存储:将Field的值存储在文档中,存储在文档中的Field才可以通过Document获取。
Field类 | 数据类型 | 是否分析 | 是否索引 | 是否存储 | 说明 |
---|---|---|---|---|---|
StringField(FieldName,FieldValue,Store.YES) | 字符串 | 否 | 是 | 都可以 | 这个Field用来构建一个字符串Field,但是不会进行分析,会将整个串存储在索引中。Store.YES表示存储在文档中,.NO反之。 |
LongPoint(String name,long point) | 长整型 | 是 | 是 | 否 | 仅仅让数值参与运算, 并不是存储,如果想要存储数值型的值需要StoreField。 |
StoreField(FieldName,FieldValue) | 重载方法 | 否 | 否 | 是 | 这个Field用来构建不同类型Field,用来存储。 |
TextField(FieldName,FieldValue,Store.NO) | 字符串 | 是 | 是 | 都可以 | 和StringField类似。 |
TextField(FieldName,reader) | 流 | 是 | 是 | 都可以 | 如果传入的是一个reader,Lucene会预测这是一个流。 |
添加文档
- 创建一个IndexWriter对象,需要使用IKAnalyzer作为分析器
- 创建一个Document对象
- 向Document对象中添加域
- 把文档写入索引库
- 关闭索引库
package com.lucene;
import java.io.File;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.FSDirectory;
import org.junit.Before;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;
public class IndexManager {
private IndexWriter indexWriter;
@Before
public void init() throws Exception{
// 1.创建一个IndexWriter对象,需要使用IKAnalyzer作为分析器
indexWriter =
new IndexWriter(FSDirectory.open(new File("E:\\syk").toPath()),
new IndexWriterConfig(new IKAnalyzer()));
}
@Test
public void addDocument() throws Exception{
// 2.创建一个Document对象
Document document = new Document();
// 3.向Document对象中添加域
document.add(new TextField("name", "新添加的文件名称",Field.Store.YES));
// - 不存储的话无法通过document取出
document.add(new TextField("content", "新添加的文件内容",Field.Store.NO));
document.add(new StoredField("path", "c:/temp/index"));
// 4.把文档写入索引库
indexWriter.addDocument(document);
// 5.关闭索引库
indexWriter.close();
}
}
删除文档
删除文档比较简答,分为查询删除和全部删除两种。
package com.lucene;
import java.io.File;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.FSDirectory;
import org.junit.Before;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;
public class IndexManager {
private IndexWriter indexWriter;
@Before
public void init() throws Exception{
// 1.创建一个IndexWriter对象,需要使用IKAnalyzer作为分析器
indexWriter =
new IndexWriter(FSDirectory.open(new File("E:\\syk").toPath()),
new IndexWriterConfig(new IKAnalyzer()));
}
// 查询删除
@Test
public void deleteDocument() throws Exception{
// - 删除name域中有apache关键词的文档
indexWriter.deleteDocuments(new Term("name","apache"));
indexWriter.close();
}
// 全部删除
@Test
public void deleteAllDocument() throws Exception{
// - 全部删除
indexWriter.deleteAll();
indexWriter.close();
}
}
修改文档
Lucene中修改的原理是先删除再添加。
package com.lucene;
import java.io.File;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.FSDirectory;
import org.junit.Before;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;
public class IndexManager {
private IndexWriter indexWriter;
@Before
public void init() throws Exception{
// 1.创建一个IndexWriter对象,需要使用IKAnalyzer作为分析器
indexWriter =
new IndexWriter(FSDirectory.open(new File("E:\\syk").toPath()),
new IndexWriterConfig(new IKAnalyzer()));
}
@Test
public void updateDocument() throws Exception{
// - 创建一个新的文档对象
Document document = new Document();
// - 向文档对象中添加域
document.add(new TextField("name","更新之后的文档",Field.Store.YES));
document.add(new TextField("name1","更新之后的文档1",Field.Store.YES));
document.add(new TextField("name2","更新之后的文档2",Field.Store.YES));
// - 更新操作
indexWriter.updateDocument(new Term("name","spring"), document);
// - 关闭索引库
indexWriter.close();
}
}
查询文档
使用Query的子类查询
-
TermQuery
根据关键词进行查询。
需要制定要查询的域及要查询的关键词
-
RangeQuery
范围查询
package com.lucene;
import java.io.File;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.FSDirectory;
import org.junit.Before;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;
public class SearchIndex {
private IndexReader indexReader;
private IndexSearcher indexSearcher;
@Before
public void init() throws Exception{
// 1.创建一个indexSearcher对象
indexReader =
DirectoryReader.open(FSDirectory.open(new File("E:\\syk").toPath()));
indexSearcher = new IndexSearcher(indexReader);
}
private void printResult(Query query) throws Exception {
// - 执行查询
TopDocs topDocs = indexSearcher.search(query, 10);
// - 打印总记录数
System.out.println("总记录数:"+topDocs.totalHits);
// - 遍历记录
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
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("文档内容是:"+document.get("Content"));
}
}
@Test
public void testRangeQuery() throws Exception{
// - 创建一个查询 范围查询的域必须以longpoint存储
Query query = LongPoint.newRangeQuery("size", 0l,10000l);
// - 执行查询
printResult(query);
}
}
-
QueryParser
对查询的内容先分词,然后基于分词的结果进行查询
需要添加lucene-queryparser-xxx.jar包
package com.lucene; import java.io.File; import org.apache.lucene.document.Document; import org.apache.lucene.document.LongPoint; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.FSDirectory; import org.junit.Before; import org.junit.Test; import org.wltea.analyzer.lucene.IKAnalyzer; public class SearchIndex { private IndexReader indexReader; private IndexSearcher indexSearcher; @Before public void init() throws Exception{ // 1.创建一个indexSearcher对象 indexReader = DirectoryReader.open(FSDirectory.open(new File("E:\\syk").toPath())); indexSearcher = new IndexSearcher(indexReader); } private void printResult(Query query) throws Exception { // - 执行查询 TopDocs topDocs = indexSearcher.search(query, 10); // - 打印总记录数 System.out.println("总记录数:"+topDocs.totalHits); // - 遍历记录 ScoreDoc[] scoreDocs = topDocs.scoreDocs; 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("文档内容是:"+document.get("Content")); } } @Test public void testQueryParser() throws Exception { // 创建一个QueryParser对象 参数1:默认搜索域;参数2:分析器对象 QueryParser queryParser = new QueryParser("name", new IKAnalyzer()); // 使用QueryParser对象创建一个Query对象 Query query = queryParser.parse("lucene是一个Java开发的全文检索工具包"); // - 执行查询 printResult(query); } }