Lucene索引的基本概念
在 Elasticsearch 中,术语 文档 有着特定的含义。它是指最顶层或者根对象, 这个根对象被序列化成 JSON 并存储到 Elasticsearch 中,指定了唯一 ID
文档可以被索引
{ "name": "John Smith", "age": 42, "confirmed": true, "join_date": "2014-06-01", "home": { "lat": 51.5, "lon": 0.1 }, "accounts": [ { "type": "facebook", "id": "johnsmith" }, { "type": "twitter", "id": "johnsmith" } ] }
_index
文档在哪存放
_type
文档表示的对象类别
_id
文档唯一标识
上面文档中包含字段
name、age、confirmed
注意字段对应的类型,可能是 字符串、布尔、数字等
倒排索引里,记录的是由 词项–>文档x,文档y,…文档z的这么一种关系,是一种反向的信息
词项是搜索时的一个单位
{
"query": {
"term": {
"title": "程序"
}
}
}
{
"query": {
"terms": {
"title": ["程序","性能"]
}
}
}
查询title字段中包含 “程序” 或者 “性能”的文档
词项在字段中的一次出现
{
"tokens": [
{
"token": "orj2t4r8rlgz",
"start_offset": 0,
"end_offset": 12,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "988y947mmas5zuu",
"start_offset": 13,
"end_offset": 28,
"type": "<ALPHANUM>",
"position": 1
}
]
}
Apache Lucene 将写入的所有信息组织成 inverted index 的结构形式。
倒排索引是一种将 词项 映射到 文档 的数据结构
一个 索引 由多个 段 组成
每个 段 只会写入一次,但是会被查询多次。
索引期间,一个段创建之后就不会被修改。例如,当段中的摸个文档被删除,有关它的信息会被单独保存在一个文件中,而段本身不会被修改
多个段将会在 段合并 (segment merge)阶段被合并在一起。
段合并 操作或被强制执行,或由 Lucene 的内在机制决定在某个时刻执行,
合并之后 段的数量更少,但是每个段的体积更大。段合并操作耗费 I/O 非常严重,合并期间有些不再使用的信息会被清理掉,例如被删除的文档。
对于容纳相同数据量的索引,搜索一个大段比搜索多个小段速度更快
norm 存储归一化结果,用于计算查询的相关得分。
norm 基于索引时的文档加权值 (boost)计算得出,与文档一起被索引。
使用 norm 可以让 Lucene 在建立索引时考虑不同文档的权重,代价仅仅是需要一些额外的磁盘空间 和 内存 来索引和存储 norm 信息。
词项向量 是一种针对每个文档的微星倒排索引。
词项向量 由词项 和 词项 的出现频率结对组成,还可以包含词项的位置信息。Lucene 和 Elasticsearch 默认都禁用词项向量索引,不过要启用诸如关键词高亮之类 的功能,就需要启用这个选项 。
文档导入Elasticsearch之后,会经历一个必要的分析阶段,以生成倒排索引
文本分析过程由分析器来执行,分析器包含一个 分词器、零到多个 词条过滤器 和 零到多个 字符过滤器。
Lucene 分词器 用来将 文本切割成 词条, 词条是携带各种额外信息的词项。
这些信息包括词项在原始文本中的位置和词项的长度。由分词器得到的结果被称为词条流,因为这些词条被一个接一个地推送给过滤器处理。
过滤器用来移除、修改词条流中的词条,甚至可以生成新的词条。
Lucene 中有很多现成的过滤器
小写过滤器
ASCII 过滤器
同义词过滤器
多语言词干还原过滤器
在查询时也会经过分析阶段,但是可以选择其他路径而不分析查询条件
Elasticsearch中有些查询会被分析,而有些不会被分析
例如
前缀查询 prefix query 不会被分析
匹配查询 match query 会被分析
关于 索引期 与 检索期 的查询分析,只有当查询 query 语句经过 分词过程 得到的 词项 能与索引中的词项 匹配时,才会返回预期的文档集。
例如,如果 在索引期 使用了词干还原 与 小写转换,那么在查询期,也 应该对查询串做相同的处理,否则,查询可能不会返回任何结果。