目录
一:springboot整合lucenne
在springboot中整合lucenne实现搜索。实则分为俩个步骤:第一步,读取数据在内存或者硬盘中建立索引。第二步,对索引
文件实现搜索并返回结果。
第一步:建立索引
相对而言这一步是相当消耗时间,计算过将10万条数据进行建立索引需要20几秒,这里建议使用一个异步线程或者定时任务
等等。
第二部:索引查询
通过多种query组合进行不同方式的查询
二:整合代码
1.实现简单的查询
(1)config配置:统一配置,配置索引位置索引操作以及流的各种操作
package com.lucene.lucene.config;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
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.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;
/**
* lucene的配置
* @author monxz
*
*/
public class LuceneConfig {
//索引库地址
public static String dir="D:/lucene";
//中文分词器
public static Analyzer analyzer =new IKAnalyzer(false); //最细粒度分词
//lunece版本号
public static Version version=Version.LUCENE_47;
// 写对象
private static IndexWriter writer = null;
public static void readList(List<Document> list) throws Exception{
list.forEach(o->{
try {
write(o);
} catch (Exception e) {
e.printStackTrace();
}
});
coloseWriter(writer);
}
/**
* 查询
* @param key 要查的属性
* @param value 要查的类似的值
* @throws IOException
* @throws ParseException
*/
public static List<Document> exQuery(Query query) throws Exception {
List<Document> res=new ArrayList<Document>();
//读取document文件
IndexReader reader=null;
reader = getIndexReader();
IndexSearcher search =new IndexSearcher(reader);
TopDocs topDocs = search.search(query, 10);
System.out.println("result:"+topDocs.totalHits);
ScoreDoc[] scoreDocs=topDocs.scoreDocs;
for (ScoreDoc scoreDoc:scoreDocs){
//根据文档对象ID取得文档对象
Document doc=search.doc(scoreDoc.doc);
res.add(doc);
}
coloseReader(reader);
return res;
}
//========================流操作==========
/**
* 获取IndexWriter 同一时间 ,只能打开一个 IndexWriter,独占写锁 。内建线程安全机制
* @return
* @throws Exception
*/
public static IndexWriter getIndexWriter() throws Exception {
FSDirectory fs = FSDirectory.open(new File(dir));
// 判断资源是否占用
if (writer == null || !writer.isLocked(fs)) {
synchronized (LuceneConfig.class) {
if (writer == null || !writer.isLocked(fs)) {
// 创建writer对象
writer = new IndexWriter(fs,
new IndexWriterConfig(version, analyzer));
}
}
}
return writer;
}
/**
* 关掉流
* @param reader
*/
private static void coloseReader(IndexReader reader) {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取到IndexReader 任意多个IndexReaders可同时打开,可以跨JVM。
* @return
* @throws Exception
*/
public static IndexReader getIndexReader() throws Exception {
// 创建IdnexWriter
FSDirectory fs = FSDirectory.open(new File(dir));
// 获取到读
return IndexReader.open(fs);
}
/**
* 关闭独流
* @param writer
*/
private static void coloseWriter(IndexWriter writer) {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//========索引操作===============
/**
* 删除所有的索引
*/
public static void deleteAll() throws Exception{
IndexWriter writer = null;
// 获取IndexWriter
writer = getIndexWriter();
// 删除所有的数据
writer.deleteAll();
int cnt = writer.numDocs();
System.out.println("索引条数\t" + cnt);
// 提交事物
writer.commit();
coloseWriter(writer);
}
/**
* 创建索引
* @param doc
* @throws Exception
*/
public static void write(Document doc) throws Exception{
IndexWriter iwriter = null;
iwriter=getIndexWriter();
iwriter.addDocument(doc);
//提交事务
iwriter.commit();
}
/**
* 跟新索引
* @param key
* @param value
* @param doc
* @throws Exception
*/
public static void updateIndex(String key ,String value,Document doc) throws Exception {
IndexWriter iwriter=getIndexWriter();
iwriter.updateDocument(new Term(key,value), doc);
}
}
(2)匹配各种查询
package com.lucene.lucene.util;
import java.util.List;
import javax.print.Doc;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.queryparser.classic.QueryParser.Operator;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.WildcardQuery;
import com.lucene.lucene.config.LuceneConfig;
/**
* 全属性检索,全文检索
* @author monxz
*
*
*/
public class luceneUtil {
public static void write(List<Document> doclist) throws Exception {
LuceneConfig.readList(doclist);
}
/**
* 精确查询单条件
* @param key
* @param value
* @return
* @throws Exception
*/
public static List<Document> accurateQuery(String key,String value) throws Exception {
TermQuery tq=new TermQuery(new Term(key,value));
return LuceneConfig.exQuery(tq);
}
/**
* 前缀查询单条件
* @param key
* @param value
* @return
* @throws Exception
*/
public static List<Document> pre