-
分析
-
将域Field文本 转换为 项Term
Term = fieldName + fieldValues[]
而 fieldValues 包含的是语汇单元token
分析
"The quick brown fox jumped over the lazy dog"
使用 StopAnalyzer 分析出的语汇单元
[quick] [brown] [fox] [jumped] [over] [lazy] [dog]
-
内置了四种基本的分析器,但是自定义分析器也很容易,并且有的时候很必要 P107
WhitespaceAnalyzer
SimpleAnalyzer
StopAnalyzer
StandardAnaylyzer
-
分析过程出现在了2个地方
(1) 建立索引
把域文本——>语汇单元(项)
注:只有由分析器产生的语汇单元才能被检索,或者是整体作为NOT_ANALYZED或者NOT_ANALYZED_NO_NORMS传入
分析器的分析结果对用户不可见,直接放在索引文件中
(2) 使用QueryParser进行搜索
把用户输入——>各个项
注:分析器只会接收独立的文本片段,不会接收整个表达式,例如用户输入
"president obama" +harvard +professor
时,会调用分析器3次
(3) 建立索引过程和进行搜索过程使用的分析器未必相同,要根据情况选择
-
分析只能在一个域中,把文本拆成语汇单元,不能把一个文本(例如html)拆成多个域;
把文本拆成多个域的操作叫解析,这是分析的前一个步骤
-
-
分析器Analyzer
-
是一个抽象类
public abstract class Analyzer implements Closeable { public abstract TokenStream tokenStream(String fieldName, Reader reader); ... }
TokenStream 类用于递归处理所有的语汇单元
例如 SimpleAnalyzer 长这样
public final class SimpleAnalyzer extends Analyzer { @Override public TokenStream tokenStream(String fieldName, Reader reader) { return new LowerCaseTokenizer(reader); } ... }
-
语汇单元的组成
一个语汇单元携带了一个文本值(单词本身)+其他一些元数据
(1) 偏移量
起点偏移量:语汇单元文本的起始字符在原始文本中的位置
终点偏移量:语汇单元文本的终止字符的下一个位置
作用:搜索结果高亮显示
(2) 位置增量
相对于前一个语汇单元的位置信息,一般位置增量默认值是1
位置增量 the ---1---> quick ---1---> brown ---1--->fox 偏移量 0 <------> 3 4 <--------> 9 10 <-----> 15 16<---->19
作用:跨度查询
-
TokenStream
作用:一个能在被调用后产生语汇单元序列的类
分析器链:
Reader --> Tokenizer ---> TokenFilter1 ---> TokenFilter2 ---> TokenFilter3 ---> Tokens
-
过滤顺序非常关键
StopAnalyzer1
public class StopAnalyzer1 extends Analyzer { private Set stopWords = Arrays.asList("a", "an", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"); @Override public TokenStream tokenStream(String fieldName, Reader reader) { return new StopFilter(true, new LowerCaseFilter( new LetterTokenizer(reader)), stopWords); } }
过滤顺序
LetterTokenizer ---> LowerCaseFilter ---> StopFilter
StopAnalyzer2
public class StopAnalyzer2 extends Analyzer { private Set stopWords = Arrays.asList("a", "an", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"); @Override public TokenStream tokenStream(String fieldName, Reader reader) { return new LowerCaseFilter(true, new StopFilter( new LetterTokenizer(reader)), stopWords); } }
过滤顺序
LetterTokenizer ---> StopFilter ---> LowerCaseFilter
对于
"The quick brown..."
的分析结果,StopAnalyzer1 会输出
[quick] [brown]
StopAnalyzer2 会输出
[the] [quick] [brown]
因为 StopAnalyzer2 先用 StopFilter 后用 LowerCaseFilter,StopFilter的输入中包含 The,而 The 不在 stopWords 的集合里面,所以不会被滤除
-