在 [synonym-formats] 中,我们看到了可以通过 简单扩展 、 简单收缩 、或_类型扩展_ 来指明同义词规则。 本章节我们将在这三者间做个权衡比较。
Tip
|
本节仅处理单词同义词。多词同义词又增添了一层复杂性,在 [multi-word-synonyms] 中,我们将会讨论。 |
通过 简单扩展 ,我们可以把同义词列表中的任意一个词扩展成同义词列表 所有 的词:
"jump,hop,leap"
扩展可以应用在索引阶段或查询阶段。两者都有优点 (⬆)︎ 和缺点 (⬇)︎。到底要在哪个阶段使用,则取决于性能与灵活性:
索引 | 查询 | |
---|---|---|
索引的大小 |
⬇︎ 大索引。因为所有的同义词都会被索引,所以索引的大小相对会变大一些。 |
⬆︎ 正常大小。 |
关联 |
⬇︎ 所有同义词都有相同的 IDF(至于什么是 IDF ,参见 [relevance-intro]),这意味着通用的词和较常用的词都拥有着相同的权重。 |
⬆︎ 每个同义词 IDF 都和原来一样。 |
性能 |
⬆︎ 查询只需要找到查询字符串中指定单个词项。 |
⬇︎ 对一个词项的查询重写来查找所有的同义词,从而降低性能。 |
灵活性 |
⬇︎ 同义词规则不能改变现有的文件。对于有影响的新规则,现有的文件都要重建(注:重新索引一次文档)。 |
⬆︎ 同义词规则可以更新不需要索引文件。 |
简单收缩 ,把 左边的多个同义词映射到了右边的单个词:
"leap,hop => jump"
它必须同时应用于索引和查询阶段,以确保查询词项映射到索引中存在的同一个值。
相对于简单扩展方法,这种方法也有一些优点和一些缺点:
- 索引的大小
-
⬆︎ 索引大小是正常的,因为只有单一词项被索引。
- 关联
-
⬇︎ 所有词项的 IDF 是一样的,所以你不能区分比较常用的词、不常用的单词。
- 性能
-
⬆︎ 查询只需要在索引中找到单词的出现。
- 灵活性
-
⬆︎ 新同义词可以添加到规则的左侧并在查询阶段使用。例如,我们想添加
bound
到先前指定的同义词规则中。那么下面的规则将作用于包含bound
的查询或包含bound
的文档索引:"leap,hop,bound => jump"
似乎对旧有的文档不起作用是么?其实我们可以把上面这个同义词规则改写下,以便对旧有文档同样起作用:
"leap,hop,bound => jump,bound"
当你重建索引文件,你可以恢复到上面的规则(注:
leap,hop,bound ⇒ jump
)来获得查询单个词项的性能优势(注:因为上面那个规则相比这个而言,查询阶段就只要查询一个词了)。
类型扩展是完全不同于简单收缩 或扩张, 并不是平等看待所有的同义词,而是扩大了词的意义,使被拓展的词更为通用。以这些规则为例:
"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。
您也可以有两全其美的办法,通过在索引阶段应用类型扩展同义词规则,以确保类型在索引中存在。然后,在查询阶段,
你可以选择不采用同义词(使 kitten
查询只返回 kittens 的文件)或采用同义词, kitten
的查询操作就会返回包括 kittens、cats、pets(也包括 dogs 和 puppies)的相关结果。
前面的示例规则,对 kitten
的 IDF 将是正确的,而 cat
和 pet
的 IDF 将会被 Elasticsearch 降权。然而, 这是对你有利的,当一个针对 kitten
的查询被拓展成了针对 kitten OR cat OR pet
的查询, 那么 kitten
相关的文档就应该排在最上方,其次是 cat
的文件, pet
的文件将被排在最底部。