zoukankan      html  css  js  c++  java
  • lucene02

    4、分词
    4.1 重要性
    分词是全文检索的核心。
    所谓的分词,就是将一段文本,根据一定的规则,拆分成一个一个词。

    Lucene是根据分析器实现分词的。针对不同的语言提供了不同的分析器。并且提供了一个通用的标准分析器StandardAnalyzer
    4.2 分词过程
    --说明:我们通过分析StandardAnalyzer核心源码来分析分词过程
    @Override  protected TokenStreamComponents createComponents(final String fieldName, final Reader reader) {    final StandardTokenizer src = new StandardTokenizer(getVersion(), reader);    src.setMaxTokenLength(maxTokenLength);    TokenStream tok = new StandardFilter(getVersion(), src);    tok = new LowerCaseFilter(getVersion(), tok);    tok = new StopFilter(getVersion(), tok, stopwords);    return new TokenStreamComponents(src, tok) {      @Override      protected void setReader(final Reader reader) throws IOException {        src.setMaxTokenLength(StandardAnalyzer.this.maxTokenLength);        super.setReader(reader);      }    };  }

    对应Lucene分词的过程,我们可以做如下总结:
    (1)分词的时候,是以域为单位的。不同的域,相互独立。
    同一个域中,拆分出来相同的词,视为同一个词(Term)
    不同的域中,拆分出来相同的词,不是同一个词。

    其中,Term是Lucene最小的语汇单元,不可再细分。

    (2)分词的时候经历了一系列的过滤器。如大小写转换、去除停用词等。

    4.3 分词后索引库结构
    我们这里借助前面的示例来说明

    从上图中,我们发现:
    (1)索引库中有两个区域:索引区、文档区。
    (2)文档区存放的是文档。Lucene给每一个文档自动加上一个文档编号docID。
    (3)索引区存放的是索引。注意:
    索引是以域为单位的,不同的域,彼此相互独立。
    索引是根据分词规则创建出来的,根据索引就能找到对应的文档。

    --------------------------------------------------------------------------------
    5 、Field域

    问题:我们已经知道,Lucene是在写入文档时,完成分词、索引的。那Lucene是怎么知道的呢?
    答:Lucene是根据文档中的域的属性,来确定是否要分词、创建索引的。所以,我们必须搞清楚域有哪些属性。
    5.1 域的属性

    5.1.1 三大属性

    5.1.1.1 是否分词(tokenized)
    只有设置了分词属性为true,lucene才会对这个域进行分词处理。

    在实际的开发中,有一些字段是不需要分词的,比如商品id,商品图片等。
    而有一些字段是必须分词的,比如商品名称,描述信息等。

    5.1.1.2 是否索引(indexed)
    只有设置了索引属性为true,lucene才为这个域的Term词创建索引。
    在实际的开发中,有一些字段是不需要创建索引的,比如商品的图片等。我们只需要对参与搜索的字段做索引处理。
    5.1.1.3 是否存储(stored)
    只有设置了存储属性为true,在查找的时候,才能从文档中获取这个域的值。

    在实际开发中,有一些字段是不需要存储的。比如:商品的描述信息。
    因为商品描述信息,通常都是大文本数据,读的时候会造成巨大的IO开销。而描述信息是不需要经常查询的字段,这样的话就白白浪费了cpu的资源了。
    因此,像这种不需要经常查询,又是大文本的字段,通常不会存储到索引库。

    5.1.1.2 特点
    (1)三大属性彼此独立。
    (2)通常分词是为了创建索引。
    (3)不存储这个域文本内容,也可以对这个域先分词、创建索引。

    5.2 Field常用类型
    域的常用类型有很多,每一个类都有自己默认的三大属性。如下:
    Field类 数据类型 Analyzed是否分词 Indexed是否索引 Stored是否存储
    StringField(FieldName, FieldValue,Store.YES)) 字符串 N Y Y或N
    LongField(FieldName, FieldValue,Store.YES) Long型 Y Y Y或N
    FloatField(FieldName, FieldValue,Store.YES) Float型 Y Y Y或N
    StoredField(FieldName, FieldValue) 重载方法,支持多种类型 N N Y
    TextField(FieldName, FieldValue, Store.NO) 字符串 Y Y Y或N

    --------------------------------------------------------------------------------
    6、索引库维护
    需要注意的是,索引是与文档紧密相连的,因此对索引的维护,实际上就是对文档的增删改。

  • 相关阅读:
    JAVA面试题 启动线程是start()还是run()?为什么?
    Java面试题 equals()与"=="的区别?
    Java面试题之数据库三范式是什么?
    很全的Python 面试题 github
    链家二手房 爬虫
    15个重要Python面试题 测测你适不适合做Python?
    静态链接和动态链接
    Python里的拷贝
    GIL线程全局锁 协程
    Python中的作用域
  • 原文地址:https://www.cnblogs.com/dxwen/p/11209759.html
Copyright © 2011-2022 走看看