基础
全文检索引擎工具包
1.数据源 dataSouce
2.分词器 analyzer 将完整的语句 分割成不同的词条
3.词条 term 分词后的最小单元 通过词条做查询数据
4.文档 Document lucene操作的对象
5.域字段 Field 可以看做 一个表中的column 比如文章标题 起域字段为title 文章内容可以域为 content
6.索引库 index 创建的索引文件存储在磁盘的目录
可视化工具
luke下载,注意对应的版本。
配置
resources/ext.dic
不明觉厉
高富帅
白富美
resources/stopword.dic
也
了
仍
从
以
使
resources/IKAnalyzer.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict">ext.dic;</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords">stopword.dic;</entry>
</properties>
引用
<!--lucene核心包-->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>4.10.3</version>
</dependency>
<!--第三方ik分词器使用的依赖坐标-->
<dependency>
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
</dependency>
创建index
- 索引的存储对象:IndexWriter
//创建索引的存储对象,使用IK分词器
Directory directory = FSDirectory.open(new File("D:\\luceneIndex"));
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_3,new IKAnalyzer());
IndexWriter writer = new IndexWriter(directory,config);
- 给IndexWriter添加document
//1.读取本地d盘下的文件内容
File fileDir = new File("D:\\searchsource");
//获取当前磁盘下的所有文件
File [] files = fileDir.listFiles();
//循环打印files文件内容
for (File file : files) {
System.out.println("文件的名称为:===="+file.getName());
System.out.println("文件的路径为:==="+file.getPath());
System.out.println("文件的大小为:====="+ FileUtils.sizeOf(file));
System.out.println("文件的内容为:====="+FileUtils.readFileToString(file));
//创建索引库写入的document文档对象
Document document = new Document();
/*
* StringField 特点是:不分词存储 productNum
* TextField 特点:分词存储
* LongField 存储数值的域字段
* Field.Store.YES 表示数据在索引库会被存储
* .NO 表示数据不存储
* 查询需要展示 设置为YES 不需要展示可以为NO
* */
document.add(new TextField("fileName",file.getName(), Field.Store.YES));
document.add(new StringField("filePath",file.getPath(), Field.Store.YES));
document.add(new LongField("fileSize",FileUtils.sizeOf(file), Field.Store.YES));
document.add(new TextField("fileContent",FileUtils.readFileToString(file), Field.Store.YES));
//2.writer对象添加当前的文档
writer.addDocument(document);
}
- 文档的删除、更新、保存
// 删除所有
//writer.deleteAll();
//更新:先删除匹配的内容,再添加
//Document document = new Document();
//document.add(new TextField("fileName","测试修改的文档2", Field.Store.YES));
//writer.updateDocument(new Term("fileName","spring"),document);
//直接选择close 表示文件默认提交保存
writer.close();
查询
单个字段、多字段、范围、分词、组合查询
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;
import java.io.File;
import java.io.IOException;
public class QueryIndex {
/**
* 查询所有的方法
*/
@Test
public void queryIndex(){
try {
//创建查询所有的对象
Query queryAll = new MatchAllDocsQuery();
doQuery(queryAll);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据词条查询数据
*/
@Test
public void queryByTerm(){
try {
//创建查询词条
Query queryAll = new TermQuery(new Term("fileName","传智播客"));
doQuery(queryAll);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据数值范围查询数据
*/
@Test
public void queryByRang(){
try {
//创建查询范围
Query queryAll = NumericRangeQuery.newLongRange("fileSize",1l,50l,true,true);
doQuery(queryAll);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 组合查询
* 只有should的时候,should是必须的。有了must之后,should就可有可无了。
*/
@Test
public void queryByBoolean(){
try {
//创建查询范围
BooleanQuery query = new BooleanQuery();
//定义查询对象1
Query query1 = new TermQuery(new Term("fileName","传智播客"));
//参数1是组合的对象 参数2是查询的满足要求 MUST 表示必须满足 SHOULD 表示可以满足 MUST_NOT 表示一定不能满足
// and or not
query.add(query1, BooleanClause.Occur.MUST_NOT);
Query query2 = new TermQuery(new Term("fileName","不明觉厉"));
query.add(query2, BooleanClause.Occur.MUST_NOT);
//查询所有的查询对象
Query queryAll = new MatchAllDocsQuery();
query.add(queryAll, BooleanClause.Occur.MUST);
doQuery(query);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 分词查询方式
* 多个域字段的查询解析
*/
@Test
public void queryByMulityField(){
try {
//定义用于查询的关键字字符串
String searchStr = "传智播客一个优秀";
//查询解析的对象
String [] fields = new String [] {"fileName","fileContent"};
MultiFieldQueryParser parser = new MultiFieldQueryParser(fields,new IKAnalyzer());
Query query = parser.parse(searchStr);
doQuery(query);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 提取后的通用查询方法
* @param queryAll
* @throws IOException
*/
private void doQuery(Query queryAll) throws IOException {
//创建索引库需要的查询对象
//索引的目录
Directory directory = FSDirectory.open(new File("D:\\luceneIndex"));
//读取本地索引库的对象
IndexReader reader = DirectoryReader.open(directory);
//创建索引的读取查询对象
IndexSearcher searcher = new IndexSearcher(reader);
//参数1是查询的对象 参数2是查询的数量
TopDocs topDocs = searcher.search(queryAll,10);
//topDocs的两个属性为 totalHist表示总共命中文档数量
// scoreDoc [] 表示每个文档的id和对应的分值
int totalHits = topDocs.totalHits;
System.out.println("总共命中的文档数量为:====="+totalHits);
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scoreDoc : scoreDocs) {
System.out.println("当前的文档id为:====="+scoreDoc.doc);
System.out.println("当前文档得分为:======"+scoreDoc.score);
//通过文档id获取文档对象的数据
Document document = searcher.doc(scoreDoc.doc);
System.out.println("当前文档的名称为:===="+document.get("fileName"));
System.out.println("当前文档的内容为:===="+document.get("fileContent"));
System.out.println("当前文档的大小为:===="+document.get("fileSize"));
System.out.println("当前文档的路径为:===="+document.get("filePath"));
}
}
}