在面对文章,或者某件物品的描述的时候,我们总希望可以通过搜索某些个关键字将其检索出来,而我们只使用数据的模糊匹配的时候,结果总是不尽如人意,这时候我们就需要使用lucene来进行检索了。
lucene是apache开源的一个全文检索的工具.
lucene进行全文检索的时候,先要建立一块空间存储索引,之后使用分词器对内容进行分词,并且建立对应的索引库(同时建立元数据库),而用户需要检索的时候,只要从索引库中进行检索就好。(所以将内容放入索引库是必须的)
<dependency>
<groupId>org.apache.lucenegroupId>
<artifactId>lucene-coreartifactId>
<version>4.4.0version>
dependency>
<dependency>
<groupId>org.apache.lucenegroupId>
<artifactId>lucene-analyzers-commonartifactId>
<version>4.4.0version>
dependency>
<dependency>
<groupId>org.apache.lucenegroupId>
<artifactId>lucene-analyzers-smartcnartifactId>
<version>4.4.0version>
dependency>
<dependency>
<groupId>org.apache.lucenegroupId>
<artifactId>lucene-queryparserartifactId>
<version>4.4.0version>
dependency>
<dependency>
<groupId>com.janeluogroupId>
<artifactId>ikanalyzerartifactId>
<version>2012_u6version>
dependency>
使用智能分词器来建立索引库
@Test
public void testLucene() throws IOException {
//确定索引库的位置 异常先上抛处理
FSDirectory directory = FSDirectory.open(new File("E://lucentest"));
// 创建文档对象(索引对象)
Document document = new Document();
Integer id = 1;
String title = "lucene测试的标题:好开心的标题";
String content = "lucene测试的内容:今天使用了lucene,此时一个测试的content路过";
//Field.Store.YES 建立索引,并且存储元数据
//Field.Store.NO 只有索引,没有元数据,查询的时候可以查询到,但是没有元数据
document.add(new StringField("id",id.toString(), Field.Store.YES));
document.add(new TextField("title",title,Field.Store.YES));
document.add(new TextField("content",content,Field.Store.YES));
//创建智能分词器
SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_44);
// 创建索引写出对象 传入版本信息和分词器
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_44,analyzer);
IndexWriter indexWriter = new IndexWriter(directory,indexWriterConfig);
//写出
indexWriter.addDocument(document);
//提交
//此时可进行处理 如果异常可以 回滚 indexWriter.rollback();
indexWriter.commit();
//关闭资源
indexWriter.close();
}
/**
* 进行多列查询
* 分词器要和创建索引的时候分词器相同
*/
@Test
public void testSearch() throws ParseException, IOException {
//创建分词器
SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_44);
//创建一个关键词对象
String[] filds = {"id","title","content"};
MultiFieldQueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_44,filds,analyzer);
//将搜索的关键字放入Query对象中
Query query = queryParser.parse("使用");
//读取索引库中的索引
FSDirectory directory = FSDirectory.open(new File("E://lucentest"));
DirectoryReader directoryReader = DirectoryReader.open(directory);
//创建一个查询对象
IndexSearcher indexSearcher = new IndexSearcher(directoryReader);
//通过关键词 得到TopDocs对象 传入Query 和 要返回的结果条数
TopDocs topDocs = indexSearcher.search(query,10);
//获取ScoreDoc对象
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (int i = 0; i < scoreDocs.length; i++) {
ScoreDoc scoreDoc = scoreDocs[i];
//获取document对象在索引库中的编号
int doc = scoreDoc.doc;
//通过编号得到对象 查询出来的其中一条数据
Document document = indexSearcher.doc(doc);
String id = document.get("id");
String title = document.get("title");
String content = document.get("content");
System.out.println("id:"+id+"title:"+title+"content:"+content);
}
查询结果,因为索引库只有一条数据,我们只看效果就好。。
然后呢Lucene基本使用就是这样了。
使用百度进行搜索的时候.我们会发现我们搜索的关键字在内容里面会进行高亮显示,lucene当然也可以做到了。
在来一波依赖
<dependency>
<groupId>org.apache.lucenegroupId>
<artifactId>lucene-highlighterartifactId>
<version>4.4.0version>
dependency>
接下就是修改我们的检索的代码了
1.定义高亮的显示格式。
2.选择高亮显示的内容(也就是我们的query对象了)
3.创建出我们的高亮对象
4.进行高亮处理
/**
* 进行多列查询
* 分词器要和创建索引的时候分词器相同
*/
@Test
public void testSearch() throws ParseException, IOException, InvalidTokenOffsetsException {
//创建分词器
SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_44);
//创建一个关键词对象
String[] filds = {"id","title","content"};
MultiFieldQueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_44,filds,analyzer);
//将搜索的关键字放入Query对象中
Query query = queryParser.parse("使用");
// 1.定义高亮的显示格式。 变成红色 并且加粗
SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("","");
// 2.选择高亮显示的内容(也就是我们的query对象了)
QueryScorer queryScorer = new QueryScorer(query);
// 3.创建出我们的高亮对象
Highlighter highlighter = new Highlighter(formatter,queryScorer);
//读取索引库中的索引
FSDirectory directory = FSDirectory.open(new File("E://lucentest"));
DirectoryReader directoryReader = DirectoryReader.open(directory);
//创建一个查询对象
IndexSearcher indexSearcher = new IndexSearcher(directoryReader);
//通过关键词 得到TopDocs对象 传入Query 和 要返回的结果条数
TopDocs topDocs = indexSearcher.search(query,10);
//获取ScoreDoc对象
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (int i = 0; i < scoreDocs.length; i++) {
ScoreDoc scoreDoc = scoreDocs[i];
//获取document对象在索引库中的编号
int doc = scoreDoc.doc;
//通过编号得到对象 查询出来的其中一条数据
Document document = indexSearcher.doc(doc);
String id = document.get("id");
String title = document.get("title");
String content = document.get("content");
// 4.进行高亮处理
String content1 = highlighter.getBestFragment(analyzer,"content",content);
System.out.println("id:"+id+"title:"+title+"content:"+content1);
}
}