基础

全文检索引擎工具包

  1. 1.数据源 dataSouce
  2. 2.分词器 analyzer 将完整的语句 分割成不同的词条
  3. 3.词条 term 分词后的最小单元 通过词条做查询数据
  4. 4.文档 Document lucene操作的对象
  5. 5.域字段 Field 可以看做 一个表中的column 比如文章标题 起域字段为title 文章内容可以域为 content
  6. 6.索引库 index 创建的索引文件存储在磁盘的目录

可视化工具

luke下载,注意对应的版本。

配置

resources/ext.dic

  1. 不明觉厉
  2. 高富帅
  3. 白富美

resources/stopword.dic

  1. 使

resources/IKAnalyzer.cfg.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
  3. <properties>
  4. <comment>IK Analyzer 扩展配置</comment>
  5. <!--用户可以在这里配置自己的扩展字典 -->
  6. <entry key="ext_dict">ext.dic;</entry>
  7. <!--用户可以在这里配置自己的扩展停止词字典-->
  8. <entry key="ext_stopwords">stopword.dic;</entry>
  9. </properties>

引用

  1. <!--lucene核心包-->
  2. <dependency>
  3. <groupId>org.apache.lucene</groupId>
  4. <artifactId>lucene-queryparser</artifactId>
  5. <version>4.10.3</version>
  6. </dependency>
  7. <!--第三方ik分词器使用的依赖坐标-->
  8. <dependency>
  9. <groupId>com.janeluo</groupId>
  10. <artifactId>ikanalyzer</artifactId>
  11. <version>2012_u6</version>
  12. </dependency>

创建index

  • 索引的存储对象:IndexWriter
  1. //创建索引的存储对象,使用IK分词器
  2. Directory directory = FSDirectory.open(new File("D:\\luceneIndex"));
  3. IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_3,new IKAnalyzer());
  4. IndexWriter writer = new IndexWriter(directory,config);
  • 给IndexWriter添加document
  1. //1.读取本地d盘下的文件内容
  2. File fileDir = new File("D:\\searchsource");
  3. //获取当前磁盘下的所有文件
  4. File [] files = fileDir.listFiles();
  5. //循环打印files文件内容
  6. for (File file : files) {
  7. System.out.println("文件的名称为:===="+file.getName());
  8. System.out.println("文件的路径为:==="+file.getPath());
  9. System.out.println("文件的大小为:====="+ FileUtils.sizeOf(file));
  10. System.out.println("文件的内容为:====="+FileUtils.readFileToString(file));
  11. //创建索引库写入的document文档对象
  12. Document document = new Document();
  13. /*
  14. * StringField 特点是:不分词存储 productNum
  15. * TextField 特点:分词存储
  16. * LongField 存储数值的域字段
  17. * Field.Store.YES 表示数据在索引库会被存储
  18. * .NO 表示数据不存储
  19. * 查询需要展示 设置为YES 不需要展示可以为NO
  20. * */
  21. document.add(new TextField("fileName",file.getName(), Field.Store.YES));
  22. document.add(new StringField("filePath",file.getPath(), Field.Store.YES));
  23. document.add(new LongField("fileSize",FileUtils.sizeOf(file), Field.Store.YES));
  24. document.add(new TextField("fileContent",FileUtils.readFileToString(file), Field.Store.YES));
  25. //2.writer对象添加当前的文档
  26. writer.addDocument(document);
  27. }
  • 文档的删除、更新、保存
  1. // 删除所有
  2. //writer.deleteAll();
  3. //更新:先删除匹配的内容,再添加
  4. //Document document = new Document();
  5. //document.add(new TextField("fileName","测试修改的文档2", Field.Store.YES));
  6. //writer.updateDocument(new Term("fileName","spring"),document);
  7. //直接选择close 表示文件默认提交保存
  8. writer.close();

查询

单个字段、多字段、范围、分词、组合查询

  1. import org.apache.lucene.document.Document;
  2. import org.apache.lucene.index.DirectoryReader;
  3. import org.apache.lucene.index.IndexReader;
  4. import org.apache.lucene.index.Term;
  5. import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
  6. import org.apache.lucene.search.*;
  7. import org.apache.lucene.store.Directory;
  8. import org.apache.lucene.store.FSDirectory;
  9. import org.junit.Test;
  10. import org.wltea.analyzer.lucene.IKAnalyzer;
  11. import java.io.File;
  12. import java.io.IOException;
  13. public class QueryIndex {
  14. /**
  15. * 查询所有的方法
  16. */
  17. @Test
  18. public void queryIndex(){
  19. try {
  20. //创建查询所有的对象
  21. Query queryAll = new MatchAllDocsQuery();
  22. doQuery(queryAll);
  23. } catch (Exception e) {
  24. e.printStackTrace();
  25. }
  26. }
  27. /**
  28. * 根据词条查询数据
  29. */
  30. @Test
  31. public void queryByTerm(){
  32. try {
  33. //创建查询词条
  34. Query queryAll = new TermQuery(new Term("fileName","传智播客"));
  35. doQuery(queryAll);
  36. } catch (Exception e) {
  37. e.printStackTrace();
  38. }
  39. }
  40. /**
  41. * 根据数值范围查询数据
  42. */
  43. @Test
  44. public void queryByRang(){
  45. try {
  46. //创建查询范围
  47. Query queryAll = NumericRangeQuery.newLongRange("fileSize",1l,50l,true,true);
  48. doQuery(queryAll);
  49. } catch (Exception e) {
  50. e.printStackTrace();
  51. }
  52. }
  53. /**
  54. * 组合查询
  55. * 只有should的时候,should是必须的。有了must之后,should就可有可无了。
  56. */
  57. @Test
  58. public void queryByBoolean(){
  59. try {
  60. //创建查询范围
  61. BooleanQuery query = new BooleanQuery();
  62. //定义查询对象1
  63. Query query1 = new TermQuery(new Term("fileName","传智播客"));
  64. //参数1是组合的对象 参数2是查询的满足要求 MUST 表示必须满足 SHOULD 表示可以满足 MUST_NOT 表示一定不能满足
  65. // and or not
  66. query.add(query1, BooleanClause.Occur.MUST_NOT);
  67. Query query2 = new TermQuery(new Term("fileName","不明觉厉"));
  68. query.add(query2, BooleanClause.Occur.MUST_NOT);
  69. //查询所有的查询对象
  70. Query queryAll = new MatchAllDocsQuery();
  71. query.add(queryAll, BooleanClause.Occur.MUST);
  72. doQuery(query);
  73. } catch (Exception e) {
  74. e.printStackTrace();
  75. }
  76. }
  77. /**
  78. * 分词查询方式
  79. * 多个域字段的查询解析
  80. */
  81. @Test
  82. public void queryByMulityField(){
  83. try {
  84. //定义用于查询的关键字字符串
  85. String searchStr = "传智播客一个优秀";
  86. //查询解析的对象
  87. String [] fields = new String [] {"fileName","fileContent"};
  88. MultiFieldQueryParser parser = new MultiFieldQueryParser(fields,new IKAnalyzer());
  89. Query query = parser.parse(searchStr);
  90. doQuery(query);
  91. } catch (Exception e) {
  92. e.printStackTrace();
  93. }
  94. }
  95. /**
  96. * 提取后的通用查询方法
  97. * @param queryAll
  98. * @throws IOException
  99. */
  100. private void doQuery(Query queryAll) throws IOException {
  101. //创建索引库需要的查询对象
  102. //索引的目录
  103. Directory directory = FSDirectory.open(new File("D:\\luceneIndex"));
  104. //读取本地索引库的对象
  105. IndexReader reader = DirectoryReader.open(directory);
  106. //创建索引的读取查询对象
  107. IndexSearcher searcher = new IndexSearcher(reader);
  108. //参数1是查询的对象 参数2是查询的数量
  109. TopDocs topDocs = searcher.search(queryAll,10);
  110. //topDocs的两个属性为 totalHist表示总共命中文档数量
  111. // scoreDoc [] 表示每个文档的id和对应的分值
  112. int totalHits = topDocs.totalHits;
  113. System.out.println("总共命中的文档数量为:====="+totalHits);
  114. ScoreDoc[] scoreDocs = topDocs.scoreDocs;
  115. for (ScoreDoc scoreDoc : scoreDocs) {
  116. System.out.println("当前的文档id为:====="+scoreDoc.doc);
  117. System.out.println("当前文档得分为:======"+scoreDoc.score);
  118. //通过文档id获取文档对象的数据
  119. Document document = searcher.doc(scoreDoc.doc);
  120. System.out.println("当前文档的名称为:===="+document.get("fileName"));
  121. System.out.println("当前文档的内容为:===="+document.get("fileContent"));
  122. System.out.println("当前文档的大小为:===="+document.get("fileSize"));
  123. System.out.println("当前文档的路径为:===="+document.get("filePath"));
  124. }
  125. }
  126. }