Elasticsearch NEST:明确指定ID似乎会导致搜索得分不一致

时间:2018-12-07 19:58:54

标签: elasticsearch nest

我有一个看起来像这样的模型类:

public class MySearchDocument
{
    public string ID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

    public int DBID { get; set; }
}

我们始终使用批量索引。默认情况下,我们的搜索会执行相对简单的multi_match,而将权重赋予IDName,例如:

{
    "query": {
        "multi_match": {
            "query": "burger",
            "fields": [
                "ID^1.2",
                "Name^1.1",
                "Description"
            ],
            "auto_generate_synonyms_phrase_query": true
        }
    }
}

我以前只是依靠Id inference,允许Elasticsearch出于其ID目的使用我的ID属性,但是由于一些原因,更倾向于使用DBID作为ID Elasticsearch中的属性。我尝试了3种不同的方式,分别地和组合地

  1. 批量索引时明确显示:new BulkIndexOperation<MySearchDocument>(d) { Id = d.DBID }
  2. ConnectionSettings中使用DefaultMappingFor<MySearchDocument>(d => d.IdProperty(p => p.DBID))
  3. MySearchDocument上使用属性:[ElasticsearchType(IdProperty = nameof(DBID))]

所有这些似乎都能按预期工作;已将建立索引的文档中的_id字段设置为我的DBID属性。但是,在我的集成测试中,搜索结果并非预期。具体来说,我进行了以下测试:

  1. 从头开始创建新索引。
  2. 使用少量MySearchDocument来填充它
  3. 在索引上发布Refresh只是为了确保索引已准备就绪。
  4. 进行搜索。
  5. 断言结果按预期顺序返回。

根据ID推断,此测试始终通过。当使用以上任何一种或所有技术切换ID字段时,它可能通过 的时间是一半。查看原始结果,总是返回正确的文档,但是对于同一文档,_score经常会因测试运行而异。有时变化的分数是与ID字段与搜索字词匹配的文档相关联的分数,有时则是不同文档的分数。

我尝试对测试进行编码,使其能够重复并行运行。我尝试在发出Refresh后的 中等待几秒钟,以确保索引已准备就绪。这些都没有影响-测试通过Id推断始终一致,如果没有,则始终不一致。我知道这个世界上没有什么是真正随机的,所以我觉得我一定在这里缺少任何东西。让我知道更多细节是否有帮助。预先感谢。

1 个答案:

答案 0 :(得分:3)

每个分片都会计算出搜索相关性得分,并且基于_id值的哈希算法可以确定给定文档将被索引到哪个主分片中。

听起来很像,就像您在N > 1个主要分片中为文档的一个小样本建立索引时所看到的那样;在这种情况下,本地相关性分数可能会有所不同,以至于在返回的某些奇特外观_score中表现出来。随着文档数量的增加和分布的均匀,本地分片分数的差异将减小。

出于测试目的,您可以采取几种方法来克服此问题:

  1. 使用单个主分片

  1. 发出搜索请求时,请使用dfs_query_then_fetch。这告诉Elasticsearch首先获取局部相关性分数,以便计算全局相关性分数,然后将全局分数用于_scoreThere is a slight overhead to using dfs_query_then_fetch

还请参阅Elasticsearch权威指南中的"Relevance is Broken!"部分;尽管该指南指的是Elasticsearch 2.x,但其中大部分仍然与更高版本相关。