Lucene StringField 还是 KeywordAnalyzer?

问题描述 投票:0回答:1

我对 Lucene 的理解还很陌生,但我知道

StringField
是索引的但不是标记化的,因此原始字符串“按原样”存储而不是被分解。这是否意味着 Lucene 在索引 StringField 时实际上会忽略正在使用的任何分析器?

看起来

KeywordAnalyzer
执行与 StringField 相同的功能,即它存储原始文本而不是对其进行标记。你什么时候会使用其中一种而不是另一种?当您可以只使用 StringField 时,使用(例如)TextField + KeywordAnalyzer 似乎很奇怪。

lucene
1个回答
0
投票

这是否意味着 Lucene 在索引

StringField
时实际上会忽略正在使用的任何分析器?

是的,这是正确的。


KeywordAnalyzer
StringField
您什么时候会使用其中一种而不是另一种?

我知道需要

KeywordAnalyzer
的最常见场景是执行搜索时,而不一定是索引时。在这种情况下,它不是“使用一个而不是另一个” - 它更多是关于需要使用
KeywordAnalyzer
,因为你选择如何使用
StringField

考虑以下场景:

您有一个名为

StringField
postal_code
,用于自然包含空格的数据 - 例如
SW1A 1AA
等值。您想保留这些空间。

索引后,该字段包含未标记化的值(不是

SW1A
1AA
,而只是
SW1A 1AA
)。我们假设还有其他字段使用标准分析器和
TextField
字段以更传统的方式进行标记。

现在您想要搜索您的数据。

假设您要搜索该

postal_code
字段。它必须是“精确”搜索,因为数据未标记化。我们暂时忽略大小写问题。 如果您尝试搜索

postal_code:"SW1A 1AA"

,您的查询将失败。至少在 Java 中,它实际上会抛出运行时错误。我认为 Lucene .Net 也是如此。

这是因为您使用了包含 

"SW1A 1AA"

的查询,这是一个

phrase
- 双引号中包含的值。 短语需要在索引中创建位置数据,以便 Lucene 知道它需要找到紧随其后的标记

SW1A

。但是,名为

1AA
StringField
不会生成任何此类位置数据(与常规
postal_code
字段不同)。
因此,您可以在搜索时使用 
TextField
来搜索

此特定字段

- 您的搜索将按预期进行。

这个例子可能看起来有点做作——我不会不同意。在 Lucene 中,通常可以有不止一种方法来获得您想要的东西。您更有可能使用 KeywordAnalyzer 并确保在索引数据之前以某种方式清理数据 - 例如,从邮政编码中删除空格;或从信用卡号中删除连字符,等等...

只是为了跟进有关位置数据的这一点:默认情况下,文本字段不仅对数据进行标记,而且还捕获原始文本中每个标记的位置 - 从而实现一系列不同类型的查询。一个例子是
邻近搜索


搜索中的短语StringField只是一种特定类型的邻近搜索。


© www.soinside.com 2019 - 2024. All rights reserved.