基础
全文检索引擎工具包
1.数据源 dataSouce2.分词器 analyzer 将完整的语句 分割成不同的词条3.词条 term 分词后的最小单元 通过词条做查询数据4.文档 Document lucene操作的对象5.域字段 Field 可以看做 一个表中的column 比如文章标题 起域字段为title 文章内容可以域为 content6.索引库 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 {/*** 查询所有的方法*/@Testpublic void queryIndex(){try {//创建查询所有的对象Query queryAll = new MatchAllDocsQuery();doQuery(queryAll);} catch (Exception e) {e.printStackTrace();}}/*** 根据词条查询数据*/@Testpublic void queryByTerm(){try {//创建查询词条Query queryAll = new TermQuery(new Term("fileName","传智播客"));doQuery(queryAll);} catch (Exception e) {e.printStackTrace();}}/*** 根据数值范围查询数据*/@Testpublic void queryByRang(){try {//创建查询范围Query queryAll = NumericRangeQuery.newLongRange("fileSize",1l,50l,true,true);doQuery(queryAll);} catch (Exception e) {e.printStackTrace();}}/*** 组合查询* 只有should的时候,should是必须的。有了must之后,should就可有可无了。*/@Testpublic void queryByBoolean(){try {//创建查询范围BooleanQuery query = new BooleanQuery();//定义查询对象1Query query1 = new TermQuery(new Term("fileName","传智播客"));//参数1是组合的对象 参数2是查询的满足要求 MUST 表示必须满足 SHOULD 表示可以满足 MUST_NOT 表示一定不能满足// and or notquery.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();}}/*** 分词查询方式* 多个域字段的查询解析*/@Testpublic 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"));}}}
