弹性搜索对多个索引进行评分

时间:2015-10-30 09:28:31

标签: elasticsearch

我有一年中任何一季度的指数(“index-2015.1”,“index-2015.2”......)

每个索引上有大约3000万个文档。

文档有一个文本字段('title')

我的文档排序方法是(1)_score(2)创建日期

问题是:

在所有索引的“标题”字段上搜索某些文本时(“index-201 *”),第一个结果始终来自一个索引。

让我说如果我正在搜索'title = home',我在“index-2015.1”上有10k文件,其中title = home,10k文件在“index-2015.2”上,title = home,那么第一个结果就是所有文件从“index-2015.1”(而不是“index-2015.2”,或混合),即使是“index-2015.2”,也有“创建日期”的文件高于“index-2015.1”。

这是有原因的吗?

2 个答案:

答案 0 :(得分:5)

原因可能是分数是指数的特定分数。因此,如果您确实有多个索引,则每个索引的文档结果分数(略微)会有所不同。

简单地说,匹配文档的分数取决于查询术语及其在索引中的出现次数。分数是根据索引计算的(实际上,默认情况下甚至是每个单独的分片)。弹性搜索有一些标准化,但我不知道那些细节。

我真的不能很好地解释它,但这里有关于得分的文章。我想你至少要阅读关于TF / IDF的部分内容。我认为,应该解释为什么你得到不同的分数。

https://www.elastic.co/guide/en/elasticsearch/guide/current/scoring-theory.html

编辑:

所以,在我的机器上稍微测试之后,似乎可以使用另一个search_type来获得适合你的情况的分数。

POST /index1,index2/_search?search_type=dfs_query_then_fetch
{
    "query" : {
       "match": {
          "title": "home"
       }
    }
}

重要的部分是 search_type = dfs_query_then_fetch 。如果您正在编写java或类似的东西,应该有一种方法在请求中指定它。有关search_types的详细信息,请参阅documentation

基本上它会首先收集所有受影响的分片(+索引)上的术语频率。因此,应该对所有这些进行推广。

答案 1 :(得分:1)

根据Andrei Stefan和Slomo的说法,指数提升解决了我的问题:

   body={ 
       "indices_boost" : { "index-2015.4" : 1.4, "index-2015.3" : 1.3,"index-2015.2" : 1.2 ,"index-2015.1" : 1.1 }
        }

编辑:

使用search_type = dfs_query_then_fetch(如Slomo所述)将以更好的方式解决问题(取决于您的商业模式......)