是否切词:对关键词是否切分,举例,姓名域的一个值:"张三" , 是否切分成"张"、"三"等等多个term。
是否索引:建立索引的时候是否对该字段域对应的数据建立索引。是不是放到倒排表中,此域的关键字与document之间的对应关系存不存在即反向关系存不存在,通过term能不能定位到document
是否存储:对此字段域的数据进行获取时,是否能还原! document.get("fieldName") 能不能得到内容
//先写着,把打分过程捋一捋,再完善
FieldType fieldType = new FieldType(); // 存储设置 fieldType.setStored(true); //索引设置 fieldType.setIndexed(true);// 是否索引 索引了才能被搜索到 fieldType.setIndexOptions(IndexOptions.DOCS_ONLY);//仅仅存储文档,词频和位置信息被忽略 fieldType.setOmitNorms(true);//标准化因子是否对此字段忽略生效,true忽略 影响评分 fieldType.setStoreTermVectorOffsets(false);//词向量里面是否存储词元字符偏移量 节省存储 fieldType.setStoreTermVectorPayloads(false);//词向量里面是否存储负载因子 可加快查询速度 、影响评分 fieldType.setStoreTermVectorPositions(false);//词向量里面是否存储位置 节省存储 fieldType.setStoreTermVectors(false);//是否存储词向量 fieldType.setTokenized(true);// 是否被分词
存储域选项:Field.Store
YES: 域中的内容全部存储到文件中,方便进行文本的还原!
NO:document.get(String name),无法得到值
索引域选项:Field.Index
ANALYZED,分词之后再建立索引,适用于标题、内容等
NOT_ANALYZED,索引,但不切词,身份证号,ID等,适用精确查询(说是说不切词,其实还是有一个切词的,就是值本身),不切分,其实默认就可以当做keywordAnalyzer了,其他任何切词器对它都失效了
ANALYZED_NO_NORMS,分词但不存储norms信息,norms中包括了创建索引的时间、权值即排序等信息
NOT_ANALYZED_NO_NORMS
,不分词也不存储
NO,不进行索引
一个域为什么会被存储(store)而不被索引(Index)呢?在一个文档中的所有信息中,有这样一部分信息,可能不想被索引从而可以搜索到,但是当这个文档由于其他的信息被搜索到时,可以同其他信息一同返回。没有经过切词,根本就不会有这个term!但是存储了原始内容
A term vector: 词向量
is a list of the document's terms and their number of occurrences in that document.
offset:偏移量
比如要存储如下词:term,termagancy,termagant,terminal
position:位置增量
1 1 1 1 position位置增量
how are you thank you
0-3 4-7 8-11 12-17 18-21 offset
停用词过滤之后
1:how[0-3]
2:you[8-11] position位置增量为2了
Offset(偏移):反向索引中保存term时,后面的词仅仅保存前缀在词中的偏移,基于数字的,获得token的位置,多用于加亮
position(位置):位置是基于term的,当你要用到的它的位置信息,比如中间是否间隔了term: phrasequery.setslop;
payload(负载因子):当要存储的信息很多的时候,存放在倒排表里,利用跳跃表,有利于大大提高搜索速度,还可以存储一些自己的信息,用户可以根据自己存储的信息,来影响Lucene的打分
词向量:used to locate specific documents in the data file,高亮
1.TypeAttributeImpl
分词的词汇类型,默认值为“word”
2.OffsetAttributeImpl
Token分词的起始字符,结束字符偏移量
3.PositionIncrementAttribute
它表示tokenStream中的当前token与前一个token在实际的原文本中相隔的词语数量
4.PositionLengthAttributeImpl
Token所占用的位置个数
举例:
原文本:I'm a student. these are apples
TokenSteam: [1: I'm ] [2:a] [3:student] [4:these] [5:are ] [6:apples]
(1) TermAttribute: 表示token的字符串信息。比如"I'm"
(2) TypeAttribute: 表示token的类别信息(在上面讲到)。比如 I'm 就属于,有撇号的类型
(3) OffsetAttribute:表示token的首字母和尾字母在原文本中的位置。比如 I'm 的位置信息就是(0,3)
(4) PositionIncrementAttribute:这个有点特殊,它表示tokenStream中的当前token与前一个token在实际的原文本中相隔的词语数量。
比如: 在tokenStream中[2:a] 的前一个token是[1: I'm ] ,它们在原文本中相隔的词语数是1,则token="a"的PositionIncrementAttribute值为1。如果token是原文本中的第 一个词,则默认值为1。因此上面例子的PositionIncrementAttribute结果就全是1了。
如果我们使用停用词表来进行过滤之后的话:TokenSteam就会变成: [1: I'm ] [2:student] [3:apples]这时student的PositionIncrementAttribute值就不会再是1,而是与[1: I'm ]在原文本中相隔词语数量=2。而apples则变成了3。
那么这个属性有什么用呢,用处很大的。假如我们想搜索一个短语student apples(假如有这个短语)。很显然,用户是要搜索出student apples紧挨着出现的文档。这个时候我们找到了某一篇文档(比如上面例子的字符串)都含有student apples。但是由于apples的PositionIncrementAttribute值是3,说明肯定没有紧挨着,就不会被搜索到。轻而易举 的解决了短语搜索的难题哦。
phrasequery,是可以解决类似 查询海南,不会召回南海的问题,同样还可以实现模糊查询,但是仅仅限于term之间,term之间才可以设置slop。
例如:张ax1111,分词为张 ax1111,phrasequery可以解决不召回ax1111张的问题,但是没有模糊功能了,只能精确(张ax111*也不行),N-gram可以解决此类问题。
precisionStep 数值类型的值转换成字符串类型的值时,影响切分之后term的个数!
precisionStep 越小那么被“切”成的的字符串就会多。precisionStep 越小则value被“切”成的term就越多,也就是说索引体积将会增大。被“切”分的term越多则可能在NumericRangeQuery中被细分 的小区间中存在的可能性也就越高,那么查询遍历的次数也就越少,性能也就越好。因此,理想的precisionStep只能依据自己的测试而获取。同时请注意如果只是对其进行sort而不需要范围查询可以将precisionStep=Integer.MAX_VALUE。这样只会生成一个term,从而不会增大索引体积。