我最近开始使用elasticsearch,所以如果这是一个“基本”问题我会道歉。我也一直在将我们的材料从ES版本1.3迁移到2.4(!),所以在这个过程中有些东西已经破坏,以及过去工作的查询/等等不再做(或给出“坏”结果) 。我已经解决了一些这些问题,但这是一个难题。
我已经阅读了docs关于如何进行相关性评分的信息。我的索引用模式标记器处理(只是分成单词),然后使用小写过滤器和ngram过滤器(最小长度为1,最大长度为3)进行处理。
现在,如果我搜索字母“a”,那么我应该首先获得相对较短的文档,对吧?因此,例如“亚洲”(其包含所需令牌的两个实例)应该得分高于“Astasia-abasia”(其具有六个),因为其令牌的比例更多等于“a”。比例性由术语频率和字段规范来计算。大!这就是我要的。但是......
事实上,“亚洲人”甚至没有出现在前5000次点击中!当我看?explain
时,我看到fieldNorm存在,但总是等于1.这是为什么?我该如何解决?
我正在使用的索引代码在这里:
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"analysis": {
"analyzer": {
"ngram_analyzer": {
"tokenizer": "pattern_tokenizer",
"filter": [ "lowercase", "ngram_filter" ]
}
},
"tokenizer": {
"pattern_tokenizer": {
"type": "pattern",
"pattern": "[\\]\\[{}()/ ,:;\"&]+"
}
},
"filter": {
"ngram_filter": {
"type": "ngram",
"min_gram": "1",
"max_gram": "3"
}
}
}
},
"mappings": {
"terms": {
"properties": {
"code": {
"analyzer": "ngram_analyzer",
"search_analyzer": "keyword",
"type": "string",
"norms": {
"enabled": true,
"loading": "eager"
}
},
"codeAbbr": {
"analyzer": "ngram_analyzer",
"search_analyzer": "keyword",
"type": "string",
"norms": {
"enabled": true,
"loading": "eager"
}
},
"term": {
"analyzer": "ngram_analyzer",
"search_analyzer": "keyword",
"type": "string",
"norms": {
"enabled": true,
"loading": "eager"
}
}
}
}
}
}
我觉得我甚至不必指定规范属性(我觉得上面应该是默认值)但是没关系。如果我把它们取出或放入,答案是一样的。如何使fieldNorm正常工作?
答案 0 :(得分:3)
答案结果与我预期的有些不同;我希望这个答案能帮助别人节省我的时间。我在我读过的文档中没有看到这个,但是通过实验发现了它。我非常具体的问题可以通过使用ngram标记器而不是ngram过滤器来解决,但让我解释一下这是为什么。
当计算fieldNorm时,问题是,这就是ngram过滤器和标记器不同的原因之一。
fieldNorm
基于文档中的令牌数量,使用文档1/sqrt(#tokens)
中给出的公式;分母中可能有也可能没有+1,这取决于你问的对象,但这个问题并不重要。重要的是,#tokens
数字在标记化之后计算,但在过滤之前计算 。
据我所知,这对ngram和edge ngram过滤器来说很重要,因为它们是唯一改变文档中令牌数量的过滤器,所以也许这就是为什么它没有在文档中突出解释。但是这里有几个用例来解释为什么这很重要:
假设您的文档包含长短语 - 可能是描述? - 并使用标准的标记器或其他任何方式进行标记。那么你的字段规范主要基于单词的数量。这可能是你想要的;这取决于你的用例。这样,搜索在单词数量方面倾向于使用较短的文档(但使用长单词不会影响您的搜索)。如果使用ngram tokenizer,则fieldNorm与字符数成比例;因此,如果你使用了很多小词,而我使用的词数更少但更大,我们的分数可能相同。通常不是你想要的。
现在假设您的文件由单个单词或非常短的短语组成(如我的)。如果使用标准标记化器进行标记,则大多数文档将具有fieldNorm 1,因为它们是单个单词。但是,我希望我的搜索优先考虑较短的单词(作为“常用单词”的近似值),所以这没有用。相反,我将使用ngram标记器,因此较长的单词被推到底部,较短的单词浮动到顶部。