【Java劝退师】Lucene 知识脑图 - 信息搜索库

840 阅读4分钟

Lucene

Lucene

信息搜索库

一、解决的问题

  1. 数据量过多时,数据库搜索速度慢
  2. 数据库查找结果无法进行相关度排序

二、概念

1. 数据类型

  1. 结构化数据 - 固定格式 或 有限长度 的数据 - 数据库的数据、元数据
  2. 非结构化数据 (全文数据) - 不定长 或 无固定格式 的数据 - 邮件、Word文档

数据库适合结构化数据的精确查找(非结构化、模糊查找 不适合)

2. 查找方法

  1. 顺序扫描 - 从头看到尾 - 数据量大查找慢
  2. 全文搜索 - 使用词创建索引,并记录词出现的次数与位置,检索时根据词进行查找 - 站内搜索、搜索引擎

3. 索引类型

  1. 正排索引 - KEY : 文档ID,Value : [ 单词1 : 出现次数、出现位置列表,单词2 : 出现次数、出现位置列表 ... ]

    在多文档中查找时,需要进行全文档扫描

  2. 倒排索引 - KEY : 关键词,Value : [ 文档1 ID : 出现次数、出现位置列表, 文档2 ID : 出现次数、出现位置列表]

    可以根据单词,快速获取包含该单词的文档列表

    词(Term) → 文档(Document)

4. 分词器

  1. 停用词 - 无意义的词 - 的、在、是、啊、a、an、the
  2. 扩展词 - 希望分词器切出的词
  3. 过滤 - 去除标点符号、去除停用词、大写转小写、词形还原(复数转单数、过去式转现在式)

三、特性

  1. 稳定、性能高

    • 每小时索引 150 GB

    • 1 MB 内存运行

  2. 高效、准确地搜索算法

  3. 开源、跨平台( Java )

四、运行流程

1. 索引创建

  1. 取得原始数据(Document) - 网页、数据库、文档
  2. 将数据进行词法分析(分词器 Tokenizer),形成 系列词 (Term)
  3. 将系列词传给 索引组件 (Indexer) 形成倒排索引
  4. 将倒排索引写入到磁盘

2. 搜索

  1. 分析查找语句,获取系列词 (Term)
  2. 使用语法分析获得查找树
  3. 将索引存储从硬盘读到内存
  4. 利用查找树搜索索引,得到所有系列词对应的文档列表
  5. 将文档列表进行交叉、去重 ( AND、OR、NOT ),得到结果文档
  6. 将结果文档进行相关度排序,并返回

五、Field 域

索引(Index)[目录] → 段(segment)[倒排索引集合] → 文档(Document)[一笔数据] → 域(Field)[字段] → 词(Term)[值]
10份Document → 1个Segment, 10个Segment → 1个Segment (默认一个Segment包含最大文档数为 Int32.MaxValue)

1. 属性

  • tokenized 是否分词 - 目的 : 方便索引

    是 : 商品名称、商品简介

    否 : 订单号、身分证号

  • indexed 是否索引 - 目的 : 搜索

    是 : 商品名称、商品简介、订单号、身分证号

    否 : 文档路径、图片路径

  • stored 是否存储 - 目的 : 直接获取

    是 : 商品名称、订单号

    否 : 内容过大,EX : 商品简介

2. 常用类型

  1. StringField - 字符串 - 不分词、会索引
  2. TextField - 字符串 - 会分词、会索引
  3. IntPoint、FloatPoint、DoublePoint - 数值 - 会索引、不存储,需存储要搭配 StoredField
  4. StoredField - 各种类型 - 不分词、不索引、只存储 - 图片路径

六、查找类型

  1. TermQuery 词项查找 - 不使用分词器,精确查找 - 订单号、分类号
  2. BooleanQuery 布尔查找 - 实现组合条件查找
    • MUST : 必须包含
    • MUST_NOT : 不包含
    • SHOULD : 包含
  3. PhraseQuery 短语查找 - 使用分词器查找
  4. SpanTermQuery 跨度查找 - 指定词之间最多横跨多少距离
  5. FuzzyQuery 模糊查找 - 使用通配符进行查找、纠错查找
    • * : 0~N 个字符
    • ? : 1 个字符
    • \ : 转译符
  6. newRangeQuery 数值(范围)查找

七、相关度得分因子

正相关

  1. 一篇文档中包含的搜索词数量
  2. 搜索词在文档中的词频
  3. 文档、域、词 权重

负相关

  1. 逆文档频率 - 搜索词在其它文档出现的频率
  2. 文档长度

八、优化

  1. 请求过滤 - 布隆过滤器
  2. IndexWriter 参数
    • setMaxBufferedDocs - 写入 segment 前保存的 document 数目,值加大提高索引速度,耗内存 - 【默认】10
    • mergeFactor - 合并索引片段数量 - 值加大降低索引合并开销、降低搜索速度 - 【默认】10
  3. 使用 SSD 硬盘
  4. 屏蔽 打分/排序 机制
  5. 选择索引库
    • SimpleFSDirectory - 简单、并发能力差
    • NIOFSDirectory - 并发能力强,Windows 系统下有 BUG
    • MMapDirectory - 基于内存操作【推荐】