我有一个看起来像这样的模型类:
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
,而将权重赋予ID
和Name
,例如:
{
"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种不同的方式,分别地和组合地:
new BulkIndexOperation<MySearchDocument>(d) { Id = d.DBID }
ConnectionSettings
中使用DefaultMappingFor<MySearchDocument>(d => d.IdProperty(p => p.DBID))
MySearchDocument
上使用属性:[ElasticsearchType(IdProperty = nameof(DBID))]
所有这些似乎都能按预期工作;已将建立索引的文档中的_id
字段设置为我的DBID
属性。但是,在我的集成测试中,搜索结果并非预期。具体来说,我进行了以下测试:
MySearchDocument
来填充它Refresh
只是为了确保索引已准备就绪。根据ID推断,此测试始终通过。当使用以上任何一种或所有技术切换ID字段时,它可能通过 的时间是一半。查看原始结果,总是返回正确的文档,但是对于同一文档,_score
经常会因测试运行而异。有时变化的分数是与ID
字段与搜索字词匹配的文档相关联的分数,有时则是不同文档的分数。
我尝试对测试进行编码,使其能够重复并行运行。我尝试在发出Refresh
后的 中等待几秒钟,以确保索引已准备就绪。这些都没有影响-测试通过Id推断始终一致,如果没有,则始终不一致。我知道这个世界上没有什么是真正随机的,所以我觉得我一定在这里缺少任何东西。让我知道更多细节是否有帮助。预先感谢。
答案 0 :(得分:3)
每个分片都会计算出搜索相关性得分,并且基于_id
值的哈希算法可以确定给定文档将被索引到哪个主分片中。
听起来很像,就像您在N > 1
个主要分片中为文档的一个小样本建立索引时所看到的那样;在这种情况下,本地相关性分数可能会有所不同,以至于在返回的某些奇特外观_score
中表现出来。随着文档数量的增加和分布的均匀,本地分片分数的差异将减小。
出于测试目的,您可以采取几种方法来克服此问题:
或
dfs_query_then_fetch
。这告诉Elasticsearch首先获取局部相关性分数,以便计算全局相关性分数,然后将全局分数用于_score
。 There is a slight overhead to using dfs_query_then_fetch
。还请参阅Elasticsearch权威指南中的"Relevance is Broken!"部分;尽管该指南指的是Elasticsearch 2.x,但其中大部分仍然与更高版本相关。