英文版地址: https://www.elastic.co/guide/en/elasticsearch/guide/current/synonyms-expand-or-contract.html
本书基于 Elasticsearch 2.x 版本,有些内容可能已经过时。
同义词的扩展或收缩edit
在 同义词格式 中,我们看到了可以通过 简单扩展(simple expansion
) 、 简单收缩(simple contraction
) 、或 类型扩展(generic expansion
) 来指明同义词规则。
本章节我们将在这三者间做个权衡比较。
本节仅处理单词同义词。多词同义词又增添了一层复杂性,在 多词同义词和短语查询 中,我们将会讨论。
简单扩展 (Simple Expansion)edit
通过 简单扩展 ,我们可以把同义词列表中的任意一个词扩展成同义词列表 所有 的词:
"jump,hop,leap"
扩展可以应用在索引阶段或查询阶段。两者都有优点 (⬆)︎ 和缺点 (⬇)︎。到底要在哪个阶段使用,则取决于性能与灵活性:
索引 | 查询 | |
---|---|---|
索引的大小 |
⬇︎ 更大, 因为所有的同义词都会被索引。 |
⬆︎ 正常大小。 |
关联 |
⬇︎ 所有同义词都有相同的逆向文档频率(IDF),这意味着更常用的词和不常用的词都拥有着相同的权重。 |
⬆︎ 每个同义词的 |
性能 |
⬆︎ 查询只需要找到查询字符串中指定单个词项。 |
⬇︎ 对一个词项的查询重写来查找所有的同义词,从而降低性能。 |
灵活性 |
⬇︎ 同义词规则不能改变现有的文件。对于有影响的新规则,现有的文件都要重建(注:重新索引一次文档)。 |
⬆︎ 同义词规则可以更新不需要索引文件。 |
简单收缩 (Simple Contraction)edit
简单收缩 ,把左边的一组同义词映射到右边的一个词:
"leap,hop => jump"
它必须同时应用于索引和查询阶段,以确保查询词项映射到索引中存在的同一个值。
相对于简单扩展方法,这种方法也有一些优点和一些缺点:
- 索引的大小
- ⬆︎ 索引大小是正常的,因为只有单一词项(term)被索引。
- 关联
-
⬇︎ 所有词项的
IDF
是一样的,所以你无法区分一个词是比较常用的还是不常用的。 - 性能
- ⬆︎ 查询只需要找到有这么一个词项(term)的索引.
- 灵活性
-
⬆︎ 新同义词可以添加到规则的左侧并在查询阶段使用。例如,我们想添加
bound
到先前指定的同义词规则中。那么下面的规则将作用于包含bound
的查询或包含bound
的文档索引:"leap,hop,bound => jump"
似乎对旧有的文档不起作用是么?其实我们可以把上面这个同义词规则改写下,以便对旧有文档同样起作用:
"leap,hop,bound => jump,bound"
重建索引时,就可以恢复到之前的规则(即:
leap,hop,bound => jump
)来获得查询单个词项的性能优势(注:因为上面那个规则相比这个而言,查询阶段就只要查询一个词了)。
类型扩展 (Genre Expansion) edit
类型扩展是完全不同于简单收缩 或扩张, 并不是平等看待所有的同义词,而是扩大了词的意义,使被拓展的词更为通用。以这些规则为例:
"cat => cat,pet", "kitten => kitten,cat,pet", "dog => dog,pet" "puppy => puppy,dog,pet"
通过在索引阶段使用类型扩展:
-
一个关于
kitten
的查询会发现关于kittens
的文档。 -
查询一个
cat
会找到关于kittens
和cats
的文档。 -
一个
pet
的查询将发现有关的kittens
、cats
、puppies
、dogs
或者pets
的文档。
或者, 在查询阶段使用类型扩展, kitten
的查询结果就会被拓展成涉及到 kittens、cats、dogs。
有个两全其美的办法: 通过在索引阶段应用类型扩展同义词规则,以确保类型(genres)在索引中存在。然后,在查询阶段,
可以选择不采用同义词(这样kitten
查询只返回与kittens
有关的文件),或 采用同义词(kitten
的查询操作就会返回包括kittens
、cats
、pets
、dogs
、puppies
的相关结果)。
前面的示例规则,kitten
的IDF
是正确的,而cat
和pet
的IDF
将会被 Elasticsearch 人为的降低。然而, 这是有利的,比如, 执行kitten 或 cat 或 pet
(即:只要其中一个匹配) 查询时使用类型扩展, kitten
相关的文档应该排在最上方,其次是cat
, 而pet
将被排在最底部。