我正在将一些旧代码从Nest 1.9.4转换为全新版本的Nest 7.4。
在旧代码中,我们从别名索引中查询,该索引返回了多种类型的对象,因此我们将对象用作通用类型,如下所示:
var response = ElasticClient.Search<object>(search)
搜索完成后,我们从响应中获取Documents集合,并根据对象的类型分离对象:var posts = response.Documents.OfType<Blog.Post>;
这是当前Nest实现的第一个问题,如果我提供“对象”作为通用类型,则会收到一个IReadOnlyCollection,其中文档的每个属性都作为一个Dictionary。它迫使我更改代码,但没什么大不了的,我知道当前实现使用的版本已经过时了,但是将这种结果转换为实际对象并不容易。
第二个问题是,如果我更改代码以查询正确的类型var response = ElasticClient.Search<Blog.Post>(search)
,elasticsearch将返回正确的命中数,但是文档属性为null,所有这些都为null。
如果我尝试使用我的类型反序列化来自服务器的响应,它将正常工作。
有人见过这种行为吗?
您将遇到的一个非常大的区别是,在NEST 1.9.4中,Elasticsearch在命中元数据中包含与查询匹配的每个命中的_type
。结合元数据中的_index
,NEST可以将每个匹配的_source
JSON对象反序列化为预期的POCO。在您的示例中,尽管您将object
指定为要返回的每个文档的类型,但是NEST仍可以根据客户端配置的索引和类型将其中一些文档反序列化为Blog.Post
。然后,这允许使用LINQ的.OfType<T>()
进行过滤以使其正常工作。
From Elasticsearch 6.0 onwards, types are being removed,因此命中元数据中不再有_type
字段供NEST用来推断文档应反序列化到哪个POCO。解决此问题的一种方法是在文档中引入一个鉴别符字段,该字段可用于确定最终应将文档反序列化为哪种POCO类型。例如,您可能考虑hooking up JsonNetSerializer
from the Nest.JsonNestSerializer nuget package和JsonNetSerializer