lucene的简单使用

1.lucene的概念解释

1.概念介绍
Lucene是apache软件项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,是用于开发检索技术实现的。
2.检索方式
情景需求:查询 雄 的汉字
顺序扫描法  每页查询汉字是否匹配 雄 匹配之后提取数据
倒排索引扫描法 通过关键字和数据的映射关系 查找记录的方式
             拼音目录 部署目录
             先通过拼音X xiong 字对应的页码
全文检索是通过倒排索引查找数据的一种方式,先通过数据和关键字的索引结构定位位置,通过位置提取数据
3.检索的使用场景
1.搜索引擎   
2.站内搜索    
3.软件内部搜索  
lucene对于电商网站的意义 提升产品的数据检索速度

2.lucene的相关术语

1.数据源 DataSource 数据的来源
2.分词器 Analyzer   切割文字为不同的关键词
3.词条 Term   分词后的最小单元
4.文档 Document  lucene操作的一个对象
5.域 Field  域字段可以理解为表中的一个列 或者java对象的一个属性
   比如一个文章 创建Document文档对象 其中包含 title 域  content 域 time 域
               创建java对象   其中   title 属性 content 属性
6.索引库 lucene创建索引库组成的目录文件

二、lucene的使用

1.创建索引库

<!--1.引入依赖-->
<dependencies>
       <!--lucene核心包-->
       <dependency>
           <groupId>org.apache.lucene</groupId>
           <artifactId>lucene-core</artifactId>
           <version>4.10.3</version>
       </dependency>
       <dependency>
           <groupId>org.apache.lucene</groupId>
           <artifactId>lucene-queryparser</artifactId>
           <version>4.10.3</version>
       </dependency>
       <!--io工具包-->
       <dependency><groupId>commons-io</groupId>
           <artifactId>commons-io</artifactId>
           <version>2.4</version>
       </dependency>
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.10</version>
       </dependency>
       <dependency>
           <groupId>com.janeluo</groupId>
           <artifactId>ikanalyzer</artifactId>
           <version>2012_u6</version>
       </dependency>

   </dependencies>
   <build>
       <plugins>
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-compiler-plugin</artifactId>
               <version>3.1</version>
               <configuration>
                   <target>1.8</target>
                   <source>1.8</source>
               </configuration>
           </plugin>

       </plugins>
   </build>

2.创建索引库

/**
* 创建索引库
*/
public class CreateIndex {

   @Test
   public void test() throws Exception {
       // 索引库的存储目录
       FSDirectory directory = FSDirectory.open(new File("d:/luceneIndex"));
       // 创建存储使用的分词器
       // StandardAnalyzer standardAnalyzer = new StandardAnalyzer(Version.LUCENE_4_10_3);
       // IK 分词器
       Analyzer analyzer = new IKAnalyzer();
       // 创建配置对象
       IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer);
       //创建索引库得到写入对象
       IndexWriter writer = new IndexWriter(directory, config);
       /*读取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("fileName", file.getPath(), Field.Store.YES));
           writer.addDocument(document);
       }
       // 关闭写入 或者提交
       writer.close();
   }
   //修改索引库的数据
   @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","spring"));
        //writer.deleteAll();;
       writer.close();
   }
}

2.分词器介绍

StandarAnalyzer      标准分词器  特点:英文按照单词分词 中文按照汉字分词
CJKAnalyzer          二分法分词器 特点:将中文两个字作为一个词语分词 我们 都是 爱学 习的 好孩 子
SmartChineseAnalyzer 聪明的中国人分词器 特点 完美解决中文的分词习惯
                                          对于英文支持不好
-------------------------第三方分词器----------------------------------------
1.支持中文良好
2.支持英文良好
3.支持扩展词 需要被分词的不支持的关键字
4.支持停用词 不需要分词的关键字
---------------------------IK分词器的使用
1.引入ik分词器的依赖
2.在创建索引库时候使用IkAnalyzer
3.引入分词器使用的配置文件
ext.dic   ---扩展词
IKAnalyzer.cfg.xml  --核心配置文件
stopword.dic  --停用词词典

三、常用api操作

查询

public class QueryIndex {
   //查询所有
   @Test
   public void findAll() throws Exception {
       // 创建查询对象
       Query query = new MatchAllDocsQuery();
       doQuery(query);
   }

   // 根据词条查询
   @Test
   public void findbyTerm() throws Exception {
       Query query = new TermQuery(new Term("fileName", "spring"));
       doQuery(query);

   }

   //数值范围查询
   @Test
   public void findbyrRange() throws Exception {
       Query query = NumericRangeQuery.newLongRange("fileSize", 1000L, 10000L, true, true);
       doQuery(query);

   }

   // 组合查询
   @Test
   public void queryByBoolean() throws Exception {
       // 组合查询对象
       BooleanQuery query = new BooleanQuery();
       Query Q = new TermQuery(new Term("fileName", "天气"));
       Query Q2 = new TermQuery(new Term("fileName", "哼哼"));
       //参数1表示被组合的查询对象 Occur常量MUST表示 必须匹配
       //                                  SHOULD表示应该匹配
       // MUST_NOT 必须不匹配
       query.add(Q, BooleanClause.Occur.MUST);
       //query.add(Q2, BooleanClause.Occur.MUST);

       Query query3 = NumericRangeQuery.newLongRange("fileSize",5000L,10000L,true,true);
       query.add(query3, BooleanClause.Occur.MUST);

       doQuery(query);

   }

   //通过查询的关键字解析查询
   @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));
   }


   //抽取的通用查询方法
   private void doQuery(Query query) throws Exception {
       // 创建索引库的读取对象
       DirectoryReader reader = DirectoryReader.open(FSDirectory.open(new File("d:/luceneIndex")));
       // 索引库的搜索对象
       IndexSearcher searcher = new IndexSearcher(reader);

       TopDocs topDocs = searcher.search(query, 100);
       System.out.println("命中数:" + topDocs.totalHits);
       // 得分和文档id的数组
       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"));
       }
   }
}

image.pngimage.png

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>



发表评论