1.概念介绍
Lucene是apache软件项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,是用于开发检索技术实现的。
2.检索方式
情景需求:查询 雄 的汉字
顺序扫描法 每页查询汉字是否匹配 雄 匹配之后提取数据
倒排索引扫描法 通过关键字和数据的映射关系 查找记录的方式
拼音目录 部署目录
先通过拼音X xiong 字对应的页码
全文检索是通过倒排索引查找数据的一种方式,先通过数据和关键字的索引结构定位位置,通过位置提取数据
3.检索的使用场景
1.搜索引擎 ---例如百度 谷歌
2.站内搜索 ---京东 天猫 电商网站内部 就业方向
3.软件内部搜索
lucene对于电商网站的意义 提升产品的数据检索速度
1.数据源 DataSource 数据的来源
2.分词器 Analyzer 切割文字为不同的关键词
3.词条 Term 分词后的最小单元
4.文档 Document lucene操作的一个对象
5.域 Field 域字段可以理解为表中的一个列 或者java对象的一个属性
比如一个文章 创建Document文档对象 其中包含 title 域 content 域 time 域
创建java对象 其中 title 属性 content 属性
6.索引库 lucene创建索引库组成的目录文件
1.引入依赖
org.apache.lucene
lucene-core
4.10.3
org.apache.lucene
lucene-queryparser
4.10.3
commons-io
commons-io
2.4
junit
junit
4.10
com.janeluo
ikanalyzer
2012_u6
org.apache.maven.plugins
maven-compiler-plugin
3.1
1.8
2.创建索引库的测试类
1.创建索引库的写入对象
//索引库的存储目录
Directory directory = FSDirectory.open(new File("D:\\luceneIndex"));
//创建存储使用的分词器
StandardAnalyzer standardAnalyzer = new StandardAnalyzer(Version.LUCENE_4_10_3);
//创建配置对象
IndexWriterConfig config = newIndexWriterConfig(Version.LUCENE_4_10_3,standardAnalyzer);
//创建索引库得到写入对象
IndexWriter writer = new IndexWriter(directory,config);
2.读取磁盘文件循环添加documen文档对象
/*读取D盘的所有文件作为数据源创建索引库
* */
File fileDir = new File("D:\\searchsource");
//获取目录下的所用文件
File[] files = fileDir.listFiles();
//循环遍历打印所有的文件信息
for (File file : files) {
//在循环过程中将文件编程document文档对象
/*
* StringField 特点:不分词存储
* TextField 特点: 分词存储
* LongField 特点:分词存储 数值类型
*
* Field.Store.YES 表示数据需要存储在索引库
* Field.Store.NO 表示创建索引结构提供查询 但不存储
* 如果需要使用的数据一定是存储起来
* */
Document document = new Document();
document.add(new TextField("fileName",file.getName(), Field.Store.YES));
document.add(new TextField("fileContent",FileUtils.readFileToString(file), Field.Store.YES));
document.add(new LongField("fileSize",FileUtils.sizeOf(file), Field.Store.YES));
document.add(new StringField("filePath",file.getPath(), Field.Store.YES));
writer.addDocument(document);
}
3.关闭写入 或者提交
writer.close();
StandarAnalyzer 标准分词器 特点:英文按照单词分词 中文按照汉字分词
CJKAnalyzer 二分法分词器 特点:将中文两个字作为一个词语分词 我们 都是 爱学 习的 好孩 子
SmartChineseAnalyzer 聪明的中国人分词器 特点 完美解决中文的分词习惯
对于英文支持不好
-------------------------第三方分词器----------------------------------------
1.支持中文良好
2.支持英文良好
3.支持扩展词 需要被分词的不支持的关键字
4.支持停用词 不需要分词的关键字
---------------------------IK分词器的使用
1.引入ik分词器的依赖
2.在创建索引库时候使用IkAnalyzer
3.引入分词器使用的配置文件
ext.dic ---扩展词
IKAnalyzer.cfg.xml --核心配置文件
stopword.dic --停用词词典
1.查询所有的数据
1.创建索引库的读取对象和搜索对象
//创建索引库的读取对象
IndexReader reader = DirectoryReader.open(FSDirectory.open(new File("D:\\luceneIndex")));
//索引库的搜索对象
IndexSearcher searcher = new IndexSearcher(reader);
2.根据需求创建查询的对象
//创建查询对象
Query query = new MatchAllDocsQuery();
3.调用query对象搜索索引库得到文档id和分值的数据
TopDocs topDocs = searcher.search(query, 100);
System.out.println("总共命中数量为:====="+topDocs.totalHits);
//得分和文档id的数组
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
4.循环遍历数组通过id得到文档的具体数据
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"));
}
2.其余查询方式
词条查询 termQuery 根据具体的词条查询数据
@Test
public void queryByTerm() throws Exception{
Query query = new TermQuery(new Term("fileName","传智播客"));
doQuery(query);
}
数值范围查询
//数值范围查询
@Test
public void queryByRange() throws Exception{
Query query = NumericRangeQuery.newLongRange("fileSize",1l,50l,true,true);
doQuery(query);
}
组合条件查询 多个查询条件组合一起筛选数据
//组合查询
@Test
public void queryByBoolean() throws Exception{
//组合查询对象
BooleanQuery query = new BooleanQuery();
Query query1 = new TermQuery(new Term("fileName","传智播客"));
Query query2 = new TermQuery(new Term("fileName","不明觉厉"));
//参数1表示被组合的查询对象 Occur常量MUST表示 必须匹配
// SHOULD表示应该匹配
//MUST_NOT 必须不匹配
query.add(query1, BooleanClause.Occur.MUST);
//query.add(query2, BooleanClause.Occur.MUST);
Query query3 = NumericRangeQuery.newLongRange("fileSize",5000L,10000L,true,true);
//query.add(query2, BooleanClause.Occur.SHOULD);
query.add(query3, BooleanClause.Occur.MUST);
doQuery(query);
}
3.查询解析
//通过查询的关键字解析查询
@Test
public void queryByParser() throws Exception{
String queryStr = "传智播客不明觉厉";
//创建插叙你的解析对象
QueryParser parser = new QueryParser("fileName",new IKAnalyzer());
Query query =parser.parse(queryStr);
doQuery(query);
}
//多个域字段的解析查询
@Test
public void queryByMultiParser() throws Exception{
String queryStr = "传智播客是一个优秀的公司";
String [] fileds = {"fileName","fileContent"};
MultiFieldQueryParser parser = new MultiFieldQueryParser(fileds,new IKAnalyzer());
doQuery(parser.parse(queryStr));
}
//修改索引库的数据
@Test
public void updateIndex() throws Exception{
//索引库的存储目录
Directory directory = FSDirectory.open(new File("D:\\luceneIndex"));
//创建存储使用的分词器
// StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_4_10_3);
Analyzer analyzer = new IKAnalyzer();
//创建配置对象
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_3,analyzer);
//创建索引库得到写入对象
IndexWriter writer = new IndexWriter(directory,config);
//创建个用于修改的document
Document document = new Document();
document.add(new TextField("fileName","测试修改", Field.Store.YES));
//根据匹配的数据删除原始文档 添加新的文档
writer.updateDocument(new Term("fileName","spring"),document);
//修改数据term必须是一个唯一标示的域字段和值 StringField
//关闭默认提交数据
writer.close();
}
//删除索引库的数据
@Test
public void deleteIndex() throws Exception{
//索引库的存储目录
Directory directory = FSDirectory.open(new File("D:\\luceneIndex"));
//创建存储使用的分词器
// StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_4_10_3);
Analyzer analyzer = new IKAnalyzer();
//创建配置对象
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_3,analyzer);
//创建索引库得到写入对象
IndexWriter writer = new IndexWriter(directory,config);
//writer.deleteDocuments(new Term("fileName","传智播客"));
writer.deleteAll();;
writer.close();
}