我有一个简单的问题,我无法回答搜索或搜索其他问题:我正在使用以下代码索引包含文件名的字段:
doc.add(new TextField(FIELD_FILENAME,filename,Field.Store.YES))
如果我索引hello.jpg然后用“hello.jpg”键搜索,那么条目就会被击中(到目前为止一直很好)。但是,如果我用“你好”搜索,我就没有点击。如果我替换'。'索引时使用另一个标点字符然后它可以工作。如果我逃脱'。'它也有效(例如索引“hello \ .jpg”我发现它正在搜索'hello')。
Lucene如何处理点?我希望与其他角色有同样的问题吗?
提前多多感谢, 斯特凡诺
答案 0 :(得分:1)
一切都取决于您使用的分析仪,因为分析仪定义了使用哪个标记器。标记化器负责标记提取,在最简单的情况下类似于定义字边界。
根据您描述的行为,我猜您使用的是StandardAnalyzer
,StandardTokenizer
使用了(ALetter | Hebrew_Letter) × (MidLetter | MidNumLet | Single_Quote) (ALetter | Hebrew_Letter)
(ALetter | Hebrew_Letter) (MidLetter | MidNumLet | Single_Quote) × (ALetter | Hebrew_Letter)
,它实现了Unicode text segmentation,其中包含以下内容:
例如,句点(U + 002E FULL STOP )含糊不清,有时用于句末,有时用于缩写,有时用于数字。
在文档中,句号字符是MidNumLet属性值的一部分,您的具体案例由WB6和WB7规则处理:
×
// UAX#29 WB5. (ALetter | Hebrew_Letter) × (ALetter | Hebrew_Letter)
// WB6. (ALetter | Hebrew_Letter) × (MidLetter | MidNumLet | Single_Quote) (ALetter | Hebrew_Letter)
// WB7. (ALetter | Hebrew_Letter) (MidLetter | MidNumLet | Single_Quote) × (ALetter | Hebrew_Letter)
// WB7a. Hebrew_Letter × Single_Quote
// WB7b. Hebrew_Letter × Double_Quote Hebrew_Letter
// WB7c. Hebrew_Letter Double_Quote × Hebrew_Letter
// WB9. (ALetter | Hebrew_Letter) × Numeric
// WB10. Numeric × (ALetter | Hebrew_Letter)
// WB13. Katakana × Katakana
// WB13a. (ALetter | Hebrew_Letter | Numeric | Katakana | ExtendNumLet) × ExtendNumLet
// WB13b. ExtendNumLet × (ALetter | Hebrew_Letter | Numeric | Katakana)
//
{ExtendNumLetEx}* ( {KatakanaEx} ( {ExtendNumLetEx}* {KatakanaEx} )*
| ( {HebrewLetterEx} ( {SingleQuoteEx} | {DoubleQuoteEx} {HebrewLetterEx} )
| {NumericEx} ( ( {ExtendNumLetEx}* | {MidNumericEx} ) {NumericEx} )*
| {HebrewOrALetterEx} ( ( {ExtendNumLetEx}* | {MidLetterEx} ) {HebrewOrALetterEx} )*
)+
)
({ExtendNumLetEx}+ ( {KatakanaEx} ( {ExtendNumLetEx}* {KatakanaEx} )*
| ( {HebrewLetterEx} ( {SingleQuoteEx} | {DoubleQuoteEx} {HebrewLetterEx} )
| {NumericEx} ( ( {ExtendNumLetEx}* | {MidNumericEx} ) {NumericEx} )*
| {HebrewOrALetterEx} ( ( {ExtendNumLetEx}* | {MidLetterEx} ) {HebrewOrALetterEx} )*
)+
)
)*
{ExtendNumLetEx}*
{ return WORD_TYPE; }
符号表示:此处不允许任何分词。
更简单地说:如果所谓的字符紧跟在和后面跟着一个字母,则不要在标点字符前后使用单词分隔符。
标准的tokenizer语法遵循以下规则:
{{1}}
总结:
如果您需要不同的行为,则必须使用更符合您目标的其他分析器。我想像LetterTokenizer这样的东西不合适,但您可以根据CharTokenizer创建自己的标记生成器来实现自己的规则。