英文版地址: https://www.elastic.co/guide/en/elasticsearch/guide/current/_fielddata_filtering.html
本书基于 Elasticsearch 2.x 版本,有些内容可能已经过时。
fielddata 过滤 (fielddata filter
)edit
设想我们正在运行一个网站允许用户收听他们喜欢的歌曲。
为了让他们可以更容易的管理自己的音乐库,用户可以为歌曲设置任何他们喜欢的标签,这样我们就会有很多歌曲被附上 rock(摇滚)
、 hiphop(嘻哈)
和 electronica(电音)
,但也会有些歌曲被附上 my_16th_birthday_favorite_anthem
这样的标签。
现在设想我们想要为用户展示每首歌曲最受欢迎的三个标签,很有可能 rock
这样的标签会排在三个中的最前面,而 my_16th_birthday_favorite_anthem
则不太可能得到评级。
尽管如此,为了计算最受欢迎的标签,我们必须强制将这些一次性的词项(term) 加载到内存中。
得益于 fielddata 过滤,我们可以控制这种状况。我们 知道 自己只对最流行的词项(term)感兴趣,所以我们可以简单地避免加载那些不太有意思的长尾项:
PUT /music/_mapping/song { "properties": { "tag": { "type": "string", "fielddata": { "filter": { "frequency": { "min": 0.01, "min_segment_size": 500 } } } } } }
|
|
|
|
只加载那些至少在本分段文档中出现 1% 的项。 |
|
忽略任何文档个数小于 500 的 分段(segment)。 |
有了这个映射,只有那些至少在 本分段 文档中出现超过 1% 的项才会被加载到内存中。我们也可以指定一个 最大
词频(term frequency),它可以被用来排除 太常用 的词项(term),比如 停用词(stopword) 。
这种情况下,词频是按照分段来计算的。这是实现的一个限制:fielddata 是按分段来加载的,所以可见的词频只是该分段内的频率。但是,这个限制也有些有趣的特性:它可以让新的受欢迎的词项(term)迅速提升到顶部。
比如一个新风格的歌曲在一夜之间受大众欢迎,我们可能想要将这种新风格的歌曲标签包括在最受欢迎列表中,但如果我们仍通过对索引做完整的计算来获取词频,我们就必须等到新标签变得像 rock
和 electronica
)一样流行。
由于频率过滤方式得以实现,新加的标签会很快作为高频标签出现在新分段内,也当然会迅速上升到顶部。
min_segment_size
参数要求 Elasticsearch 忽略某个大小以下的分段。 如果一个分段内只有少量文档,它的词频会非常粗略, 而没有任何意义。
小的分段会很快被合并到更大的分段中,这样就足够大而被计入统计数据。
通过频率来过滤词项并不是唯一的选择,我们也可以使用正则表达式来决定只加载那些匹配的项。例如,我们可以用 regex
过滤器 处理 twitte 上的消息只将以 #
号开始的标签加载到内存中。
前提是假设我们使用的分析器会保留标点符号,像 whitespace
分析器。
Fielddata 过滤对内存使用有 巨大的 影响。这种取舍很明显的特点是:我们实际上是在忽略数据。但对于很多应用,这种取舍是合理的,因为这些数据根本就没有被使用到。内存的节省通常要比包括大量而无用的长尾词项(long tail term)更为重要。