网站设计中遇到的问题,电商网站开发报价单,wordpress 小工具 功能,免费注册qq作者#xff1a;来自 Elastic spinscale 分析链中的数字标准化
在全文搜索中#xff0c;一个常见问题是如何处理数字。最基本的方法是将它们完全提取出来#xff0c;并在范围内作为真实数字进行查询#xff0c;但在很多情况下#xff0c;这需要大量分析#xff0c;而且数…作者来自 Elastic spinscale分析链中的数字标准化在全文搜索中一个常见问题是如何处理数字。最基本的方法是将它们完全提取出来并在范围内作为真实数字进行查询但在很多情况下这需要大量分析而且数字往往只是全文搜索的一部分比如 iphone 17 或 bed 1.4 m。问题是当用户输入搜索时他们对数字的理解可能与你不同。1.4 m 和 1,4 m 是相同的吗事实是美国和欧洲在大数和分数的分隔符上使用不同的字符。除此之外用户在搜索引擎中输入数字时点和逗号常常可以互换使用尤其是数字较小时。007 和 7 是相同的吗取决于你的使用场景。1.4 m 和 1.40 m 是相同的吗这取决……你明白我的意思。那么我们能做些什么来稍微标准化数字呢为了这个示例让我们使用 keep_types token filter仅保留数字丢弃分析链中的其他内容POST _analyze { text: makita führungsschiene 1.4 m, 1,4 m 1,40 1.40, tokenizer: standard, filter: [ { type: keep_types, types: [ NUM ] } ] }这只会返回看起来像数字的 token无论它们是否包含点或逗号但会排除其他内容例如普通单词比如 makita。接下来我们先统一所有带点或逗号的数字。POST _analyze { text: makita führungsschiene 1.4 m, 1,4 m 1,40 1.40, tokenizer: standard, filter: [ { type: keep_types, types: [ NUM ] }, { type: pattern_replace, pattern: (\\d)\\,(\\d), replacement : $1.$2 } ] }这只返回 1.4 或 1.40 —— 很好所以无论索引了什么或者用户搜索什么现在我们总是假设数字使用点借助 pattern_replace token filter 实现。如果不关心位置可以在最后使用 unique token filter —— 当然也可以省略 norms 以减少索引大小。你也可以去掉点只保留数字本身但这可能导致搜索 1.7 时返回 iphone 17 —— 同样这取决于是否希望这样。接下来我们去掉前导零POST _analyze { text: test 007 7 700 000 0, tokenizer: standard, filter: [ { type: keep_types, types: [ NUM ] }, { type: pattern_replace, pattern: ^0(\\d), replacement : $1 } ] }现在007 或 000 会被简化为单个数字字符。虽然这可能有用但请注意当用户搜索 007 作为零件编号时可能会返回包含 7 的所有结果从而增加歧义。接下来真正有趣的部分来了去掉尾随零但不要弄得太复杂。像往常一样如果你手头只有正则表达式你可能会想出一个复杂的正则但也许预处理可能已经是个好主意。POST _analyze { text: 0.100 0.1000 0.101 100 100.0 100.00 100.001, tokenizer: standard, filter: [ { type: keep_types, types: [ NUM ] }, { type: pattern_replace, pattern: ^(\\d)\\.([0-9])(0)$, replacement : $1.$2 } ] }这会返回至少如果你在请求中添加 filter_path**.token{ tokens: [ { token: 0.1 }, { token: 0.1 }, { token: 0.101 }, { token: 100 }, { token: 100.0 }, { token: 100.0 }, { token: 100.001 } ] }你已经可以看到这里还有一些可以改进的地方。100 和 100.0 之间真的有区别吗也许在这种情况下可以完全去掉尾随的 .0。我相信你会为此想出一个很棒的正则表达式。让我们把所有步骤整合起来POST _analyze { text: makita führungsschiene 1.4 m, 1,4 m 1,40 1.40 1.0 1.00 0.100 0.1000 0.101 0.1010 100 100.0 100.00 100.001 0.100 007 700, tokenizer: standard, filter: [ { type: keep_types, types: [ NUM ] }, { type: pattern_replace, pattern: (\\d)\\,(\\d), replacement : $1.$2 }, { type: pattern_replace, pattern: ^0(\\d), replacement : $1 }, { type: pattern_replace, pattern: ^(\\d)\\.([0-9])(0)$, replacement : $1.$2 } ] }在真实的分析链中你可能会去掉 keep_types filter并且在适用时尝试将正则表达式组合以提高速度但这大概是一个不错的起点。仔细看上面的输出你会注意到还有一个小问题0.1010 没有被简化为 0.101。因此你可能需要对正则表达式做进一步修正 —— 记住如果增加一个 token filter 有助于可读性也是可以的 还有一个实现提示。如果你想确保 pattern replace filter 只针对数字运行可以使用 condition token filter。原文https://discuss.elastic.co/t/dec-2nd-2025-en-normalizing-numbers-during-analysis/383512