我们的 Elasticsearch 索引中有多个包含文本的行
“...... 2%的牛奶......”。
用户在搜索字段中输入“2% milk”之类的查询,我们在内部将其转换为查询
title:(+milk* +2%*)
因为所有术语都应该是必需的,而且我们可能对包含“2% 乳脂”的行感兴趣。
上面的这个查询返回零命中。将查询更改为
title:(+milk* +2%)
返回合理的结果。那么为什么第一个查询中的 '*' 运算符不起作用呢?
我们的 Elasticsearch 索引中有多个包含文本的行
“...... 2%的牛奶......”。
用户在搜索字段中输入“2% milk”之类的查询,我们在内部将其转换为查询
title:(+milk* +2%*)
因为所有术语都应该是必需的,而且我们可能对包含“2% 乳脂”的行感兴趣。
上面的这个查询返回零命中。将查询更改为
title:(+milk* +2%)
返回合理的结果。那么为什么第一个查询中的 '*' 运算符不起作用呢?
除非您设置映射,否则“%”符号将在标记化过程中被删除。基本上“2%牛奶”会变成代币2
和milk
。
当您搜索“2%*”时,它会查找以下标记:2%
、2%a
、2%b
等......并且不匹配任何索引标记,因此没有命中。
当您搜索“2%”时,它将经历与索引时相同的标记化过程(您可以指定它,但默认标记化是相同的)并且您将寻找与该标记匹配的文档2
,这将给出你一击。
您可以在此处阅读有关分析/标记化过程的更多信息,并且可以通过定义自定义映射来设置所需的分析
祝你好运!
前缀和通配符查询似乎不会将分析器应用于其内容。举几个例子:
title:(+milk* +2%)
-->+title:milk* +title:2
title:(+milk* +2%*)
-->+title:milk* +title:2%*
title:(+milk* +2%3)
-->+title:milk* +(title:2 title:3)
title:(+milk* +2%3*)
-->+title:milk* +title:2%3*
+title:super\\-milk
-->+title:super title:milk
+title:super\\-milk*
-->+title:super-milk*
防止通配符查询的标记化确实有意义,因为不允许使用通配符短语查询。如果允许标记化,这似乎会引发一个问题,尤其是对于嵌入式通配符,通配符可以跨越多少个术语。