Lucene是一个非常优秀的开源的全文搜索引擎(架构),我们可以在它的上面开发出各种全文搜索的应用来。
直接上代码:
jar包
创建索引库
@Test
//创建索引库
public void testCreateIndex() throws Exception {
// 第一步:创建一个indexwriter对象。
// 1)指定索引库的存放位置Directory对象
Directory directory = FSDirectory.open(new File("D:\\temp\\index"));
//若要将索引库放在内存中
// Directory directory = new RAMDirectory();
// 2)指定一个分析器,对文档内容进行分析。
// Analyzer analyzer = new StandardAnalyzer();
Analyzer analyzer = new IKAnalyzer(); //中文支持 注意搜索时也要使用IKAnalyzer
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
IndexWriter indexWriter = new IndexWriter(directory, config);
// 第三步:创建field对象,将field添加到document对象中。
//1.读取文档所在目录
File file = new File("D:\\搜狗高速下载\\黑马javaEE\\【阶段15】luncene、Solr使用\\Lucene&solr\\01.参考资料\\searchsource");
File[] files = file.listFiles();
for (File f : files) {
// 第二步:创建document对象。
Document document = new Document();
//2.获取每个文件的field
String file_name = f.getName();
Field fileName = new TextField("fileName", file_name, Store.YES);
String file_path = f.getPath();
Field filePath = new StoredField("filePath", file_path);
Long file_size = FileUtils.sizeOf(f);
Field fileSize = new LongField("fileSize", file_size, Store.YES);
String file_content = FileUtils.readFileToString(f);
Field fileContent = new TextField("fileContent", file_content, Store.YES);
// 3.添加field到document中
document.add(fileName);
document.add(filePath);
document.add(fileSize);
document.add(fileContent);
// 第四步:使用indexwriter对象将document对象写入索引库,此过程进行索引创建。并将索引和document对象写入索引库。
indexWriter.addDocument(document);
}
// 第五步:关闭IndexWriter对象。
indexWriter.close();
}
删除索引
//获得IndexWriter
public IndexWriter getIndexWriter() throws Exception {
Directory directory = FSDirectory.open(new File("D:\\temp\\index"));
Analyzer analyzer = new IKAnalyzer();
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
return new IndexWriter(directory, config);
}
@Test
//删除全部索引库
public void testDeleteAll() throws Exception {
IndexWriter indexWriter = getIndexWriter();
indexWriter.deleteAll();
indexWriter.close();
}
@Test
//根据field删除索引
public void testDelete() throws Exception {
IndexWriter indexWriter = getIndexWriter();
Term t = new Term("fileName", "apache");
Query query = new TermQuery(t);
indexWriter.deleteDocuments(query);
indexWriter.close();
}
修改索引
@Test
//索引库修改 --先删除在添加
public void testUpdate() throws Exception {
IndexWriter indexWriter = getIndexWriter();
Term delTerm = new Term("fileName", "apache");
Document doc = new Document();
doc.add(new TextField("fileN", "测试文件名", Store.YES));
doc.add(new TextField("fileC", "测试文件内容", Store.YES));
indexWriter.updateDocument(delTerm, doc, new IKAnalyzer());
indexWriter.close();
}
查询索引
一、使用Query的子类查询
TermQuery: 通过Field和关键词查询
//根据索引查询数据
@Test
public void testSearch() throws Exception {
// 第一步:创建一个Directory对象,也就是索引库存放的位置。
Directory directory = FSDirectory.open(new File("D:\\temp\\index"));
// 第二步:创建一个indexReader对象,需要指定Directory对象。
IndexReader indexReader = DirectoryReader.open(directory);
// 第三步:创建一个indexsearcher对象,需要指定IndexReader对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
// 第四步:创建一个TermQuery对象,指定查询的域和查询的关键词。
Term term = new Term("fileName", "apache");
// Term term = new Term("fileN", "测试文件名");
TermQuery termQuery = new TermQuery(term);
// 第五步:执行查询。
TopDocs topDocs = indexSearcher.search(termQuery, 2);
// 第六步:返回查询结果。遍历查询结果并输出。
ScoreDoc[] scoreDocs = topDocs.scoreDocs;//此时查询到的是索引表中的文档ID数组
for (ScoreDoc scoreDoc : scoreDocs) {
System.out.println("文件信息:");
int doc = scoreDoc.doc; //文档ID
//根据文档ID拿到文档对象
Document document = indexSearcher.doc(doc);
System.out.println(document.get("fileName"));
System.out.println(document.get("filePath"));
System.out.println(document.get("fileSize"));
System.out.println(document.get("fileContent"));
}
// 第七步:关闭IndexReader对象
indexReader.close();
}
MatchAllQuery:查询所有
//获得indexSeacher
public IndexSearcher getIndexSearcher() throws Exception {
Directory directory = FSDirectory.open(new File("D:\\temp\\index"));
IndexReader indexReader = DirectoryReader.open(directory);
return new IndexSearcher(indexReader);
}
//打印查询结果
public void printResult(Query query, IndexSearcher indexSearcher) throws Exception {
TopDocs topDocs = indexSearcher.search(query, 10);
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scoreDoc : scoreDocs) {
int docID = scoreDoc.doc;
Document doc = indexSearcher.doc(docID);
System.out.println(doc.get("fileName"));
}
}
//查询所有 MatchAllDocsQuery
@Test
public void testQueryAll() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
Query query = new MatchAllDocsQuery();
printResult(query, indexSearcher);
indexSearcher.getIndexReader().close();
}
NumericRangeQuery:根据数值范围查询
范围查询在lucene中支持数值类型,不支持字符串类型。在solr中支持字符串类型。
//根据数值范围查询 --NumericRangeQuery.newLongRange("fileSize", 47L, 200L, true, true)
@Test //field域,最小值,最大值,是否包含最大最小值
public void testNumericRangeQuery() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
Query query = NumericRangeQuery.newLongRange("fileSize", 47L, 200L, true, true);
printResult(query, indexSearcher);
indexSearcher.getIndexReader().close();
}
BooleanQuery:组合查询
//组合查询
@Test
public void testBooleanQuery() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
BooleanQuery booleanQuery = new BooleanQuery();
Query query1 = new TermQuery(new Term("fileName", "apache"));
Query query2 = NumericRangeQuery.newLongRange("fileSize", 47L, 200L, true, false);
booleanQuery.add(query1, Occur.MUST); //必须
booleanQuery.add(query2, Occur.MUST_NOT); //必须不
// booleanQuery.add(query2, Occur.SHOULD); //都行 --恕我直言,真是睿智
printResult(booleanQuery, indexSearcher);
indexSearcher.getIndexReader().close();
}
二、使用QueryParse查询
1.QueryParse
主要通过queryParse.parse(“:“)方法的参数表达式来决定查询类型
基本查询: field : 关键字
查询全部: * : *
范围查询: field : [max TO min}
注意中间空格。括号以为左闭右开。与区间的用法是一样的
组合条件查询: +field:关键字 +field:关键字
+ :OCCUR.MUST - :OCCUR.MUST_NOT 不写就是OCCUR.SHOULD
@Test
//使用Queryparse查询
public void testQueryParse() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
QueryParser queryParse = new QueryParser("fileName", new IKAnalyzer());
Query query = queryParse.parse("*:*");//查询全部
printResult(query, indexSearcher);
indexSearcher.getIndexReader().close();
}
2.MultiFieldQueryParse:多默认域查询–没吉尔用
@Test
//多默认域查询
public void testMultiFieldQueryParse() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
String[] fields = {"fileName","fileContent"};
MultiFieldQueryParser queryParse = new MultiFieldQueryParser(fields, new IKAnalyzer());
Query query = queryParse.parse("fileName:apache");//查询全部
printResult(query, indexSearcher);
indexSearcher.getIndexReader().close();
}