zoukankan      html  css  js  c++  java
  • 全文检索Lucene框架---分词器

    一、分词器作用

      在创建索引的时候需要用法哦分词器,在使用字符串搜索的时候也会用到分词器,并且这两个地方要使用同一个分词器,否则可能会搜索不出来结果;

      分词器的作用是把一段文本中的词按规则取出所包含的所有词,对应的是Analyzer类,这是一个抽象类,切分词的具体规则是由子类实现的,所有对于不同语言的规则,要有不同的分词器;

    二、分词器分类  

      分词器为中文分词器和英文分词器:

        英文分词器是按照词汇切分,同时作词干提取,也就是将单词末尾的变化还原,使其能搜索出来,另外各种分词器对英文都支持的比较好;

        中文分词器很多实现方式,实现原理基本差不多,都是Analyzer的子类:

          标椎分词器:也叫单字分词,将中文一个字一个字的分词;  new StandardAnalyzer();

          简单分词器:根据标点符号进行分词;  new SimpleAnalyzer();

          二分法分词器:按照两个字进行分词;  new CJKAnalyzer();

          停用词分词器:和简单分词器很像,根据被忽略停用的词进行分词;  new StopAnalyzer();

          空格分词器:根据空格进行分词;  new WhitespaceAnalyzer();

          IK中文分词器:分为两种实现,一种采用智能切分,另一种是最细粒度切分算法;  new IKAnalyzer();

    三、分词器案例

    package com.zn;
    
    import org.apache.lucene.analysis.Analyzer;
    import org.apache.lucene.analysis.TokenStream;
    import org.apache.lucene.analysis.standard.StandardAnalyzer;
    import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
    
    import java.io.IOException;
    
    public class AnalyzerTest {
        public static void main(String[] args) throws IOException {
            //1、创建一个Analyzer对象
            Analyzer analyzer=new StandardAnalyzer();
            //2、调用Analyzer对象的tokenStream方法获取TokenStream对象,此对象包含了所有分词结果
            TokenStream tokenStream = analyzer.tokenStream("", "The spring Framework provides a comprehensive programming and configuration model.");
            //3、给tokenStream对象设置一个指针,指针在哪当前就在哪一个分词上
            CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
            //4、调用tokenStream对象的reset方法,重置指针,不调用会报错
            tokenStream.reset();
            //5、利用while循环,拿到分词列表的结果   incrementToken方法返回值如果为false代表读取完毕,true为没有读取完毕
            while (tokenStream.incrementToken()){
                System.out.println(charTermAttribute.toString());
            }
            //6、关闭
            tokenStream.close();
        }
    }

    效果展示:

      

    四、中文分词器

    1、Lucene自带中文分词器

      ① StandardAnalyzer:

      单字分词:就是按照中文一个字一个字地进行分词。如:“我爱中国”,
      效果:“我爱”、

      ② SmartChineseAnalyzer

      对中文支持较好,但扩展性差,扩展词库,禁用词库和同义词库等不好处理

    package com.zn;
    
    import org.apache.lucene.analysis.Analyzer;
    import org.apache.lucene.analysis.TokenStream;
    import org.apache.lucene.analysis.standard.StandardAnalyzer;
    import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
    
    import java.io.IOException;
    /*默认中文分析器*/
    public class AnalyzerTest {
        public static void main(String[] args) throws IOException {
            //1、创建一个Analyzer对象
            Analyzer analyzer=new StandardAnalyzer();
            //2、调用Analyzer对象的tokenStream方法获取TokenStream对象,此对象包含了所有分词结果
            TokenStream tokenStream = analyzer.tokenStream("", "啦啦啦我爱中国我爱中国!");
            //3、给tokenStream对象设置一个指针,指针在哪当前就在哪一个分词上
            CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
            //4、调用tokenStream对象的reset方法,重置指针,不调用会报错
            tokenStream.reset();
            //5、利用while循环,拿到分词列表的结果   incrementToken方法返回值如果为false代表读取完毕,true为没有读取完毕
            while (tokenStream.incrementToken()){
                System.out.println(charTermAttribute.toString());
            }
            //6、关闭
            tokenStream.close();
        }
    }

    效果展示:

      

    2、IKAnalyzer分词器

    ①、IKAnalyzer目录展示

      

    ②、导入依赖

    <!-- https://mvnrepository.com/artifact/com.jianggujin/IKAnalyzer-lucene -->
        <dependency>
          <groupId>com.jianggujin</groupId>
          <artifactId>IKAnalyzer-lucene</artifactId>
          <version>8.0.0</version>
        </dependency>

    ③、导入配置文件

      

     ④、AnalyzerTest

    package com.zn;
    
    import org.apache.lucene.analysis.Analyzer;
    import org.apache.lucene.analysis.TokenStream;
    import org.apache.lucene.analysis.standard.StandardAnalyzer;
    import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
    import org.wltea.analyzer.lucene.IKAnalyzer;
    
    import java.io.IOException;
    
    public class AnalyzerTest {
        public static void main(String[] args) throws IOException {
            //1、创建一个Analyzer对象
            Analyzer analyzer=new IKAnalyzer();
            //2、调用Analyzer对象的tokenStream方法获取TokenStream对象,此对象包含了所有分词结果
            TokenStream tokenStream = analyzer.tokenStream("", "啦啦啦我爱中国我爱中国!");
            //3、给tokenStream对象设置一个指针,指针在哪当前就在哪一个分词上
            CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
            //4、调用tokenStream对象的reset方法,重置指针,不调用会报错
            tokenStream.reset();
            //5、利用while循环,拿到分词列表的结果   incrementToken方法返回值如果为false代表读取完毕,true为没有读取完毕
            while (tokenStream.incrementToken()){
                System.out.println(charTermAttribute.toString());
            }
            //6、关闭
            tokenStream.close();
        }
    }

    ⑤、效果展示

      

    ⑥、注

      hotword.dic和ext_stopword.dic文件的格式为UTF-8,注意是无BOM 的UTF-8 编码。

      也就是说禁止使用windows记事本编辑扩展词典文件

    3、程序当中使用IKAnalyzer

      

    package com.zn;
    
    import org.apache.commons.io.FileUtils;
    import org.apache.lucene.document.*;
    import org.apache.lucene.index.IndexWriter;
    import org.apache.lucene.index.IndexWriterConfig;
    import org.apache.lucene.store.Directory;
    import org.apache.lucene.store.FSDirectory;
    import org.wltea.analyzer.lucene.IKAnalyzer;
    
    import java.io.File;
    import java.io.IOException;
    
    /**
     * 创建索引
     */
    public class CreatLucene {
        public static void main(String[] args) throws IOException {
            //步骤一:创建Directory对象,用于指定索引库的位置
            Directory directory= FSDirectory.open(new File("E:\accp\Y2\进阶内容\Lucene\Lucene\Index").toPath());
            //步骤二:创建一个IndexWriter对象
            IndexWriter indexWriter=new IndexWriter(directory,new IndexWriterConfig(new IKAnalyzer()));
            //步骤三:读取磁盘中文件,对应每一个文件创建一个文档对象
            File file=new File("E:\accp\Y2\进阶内容\Lucene\资料\searchsource");
            //步骤四:获取文件列表
            File[] files=file.listFiles();
            for (File item :files) {
                //步骤五:获取文件数据,封装域     参数三:是否存储
                Field fieldName=new TextField("fieldName",item.getName(), Field.Store.YES);
                Field fieldPath=new StoredField("fieldPath",item.getPath());
                Field fieldSize=new LongPoint("fieldSize", FileUtils.sizeOf(item));
                Field fieldSizeStore=new StoredField("fieldSize", FileUtils.sizeOf(item));
                Field fieldContent=new TextField("fieldContent", FileUtils.readFileToString(item,"UTF-8"), Field.Store.YES);
                //步骤六:创建文档对象,向文档对象中添加域
                Document document=new Document();
                document.add(fieldName);
                document.add(fieldPath);
                document.add(fieldSize);
                document.add(fieldContent);
                document.add(fieldSizeStore);
    
                //步骤七:创建索引,将文档对象写入到索引库
                indexWriter.addDocument(document);
            }
            System.out.println("文档对象写入索引库成功啦!!");
            //步骤八:关闭资源
            indexWriter.close();
        }
    }
  • 相关阅读:
    js例子
    js表单验证
    Python之Numpy的基础及进阶函数(图文)
    Numpy库的下载及安装(吐血总结)
    世界,你好!
    用逻辑回归模型解决互联网金融信用风险问题
    用逻辑回归模型解决互联网金融信用风险问题
    如何建立投资模型
    如何建立投资模型
    秒懂数据类型的真谛—Python基础前传(4)
  • 原文地址:https://www.cnblogs.com/Zzzzn/p/12361879.html
Copyright © 2011-2022 走看看