Azure 搜索 v11:索引复杂类型的可为空集合

问题描述

我正在将 Azure 认知搜索服务的 SDK 从 v10 更新到 v11。我已按照指南中的所有步骤进行升级,但是我注意到有关索引(合并或上传)操作的奇怪行为:UploadDocumentAsync(还有用于索引数据的其他方法) ) 当 Collection (Edm.ComplexType) 类型的属性为 null 时,操作失败,并出现以下错误

尝试读取属性内容时,从 JSON 读取器读取了“PrimitiveValue”类型的节点。但是,“StartArray”节点应该是 json。

IndexDocumentsResult response = await searchClient.UploadDocumentsAsync<T>(documents).ConfigureAwait (false);

在 v10 中没有出现这个问题。我发现的一种解决方法是将集合设置为空数组而不是空值,但我想找到更好的解决方案。

编辑: 我从 Microsoft.Azure.Search v10.1.0 升级到 Azure.Search.Documents v11.1.1 以下是用于索引数据的通用 T 类的示例:

public class IndexEntity
{
    [JsonProperty("@search.score")]
    public double Searchscore { get; set; }

    [JsonProperty("Key")]
    public Guid Id { get; set; }

    [JsonProperty("Code")]
    public string Code { get; set; }

    [JsonProperty("ComplexObj")]
    public ComplexType[] CollectionOfComplexType{ get; set; }

}

遵循 ModelObjectToIndex 的定义

public class ComplexType
{
    [JsonProperty("Id")]
    public string Id { get; set; }

    [JsonProperty("Value")]
    public string Value { get; set; }
}

基本上当 CollectionOfComplexType 属性为空时,我会收到上述错误。如果我将其设置为空数组,则不会发生错误,但如上所述我不喜欢这种解决方案,而且在旧版本中它是允许的操作(索引已成功完成)

解决方法

在这方面,我们的 Azure.Search.Documents 行为似乎发生了变化。我已打开 https://github.com/Azure/azure-sdk-for-net/issues/18169 来跟踪分辨率。

您可以在不将集合初始化为空数组的情况下解决此问题,方法是传入与我们在旧 Microsoft.Azure.Search 库中所做的类似的 JsonSerializerSettings,因为它似乎是使用 {{ 1}} 无论如何您都在使用 JsonPropertyAttribute(又名 Json.NET):

  1. 如果尚未添加对 Microsoft.Azure.Core.NewtonsoftJson 的包引用。它最近 GA 了,所以如果你是,你不需要使用预览,我认为这是因为 Newtonsoft.Json - 我们的默认序列化器 - 不会尊重你的属性重命名。

  2. 在创建 System.Text.Json 之前传入 JsonSerializerSettings,如下所示:

    SearchClient

如果可以,我们将讨论如何默认解决此问题。旧库的一大变化是能够自定义所使用的序列化程序。默认情况下,我们使用 var settings = new JsonSerializerSettings { // Customize anything else you want here; otherwise,defaults are used. NullValueHandling = NullValueHandling.Ignore,}; var options = new SearchClientOptions { Serializer = new NewtonsoftJsonObjectSerializer(settings),}; var searchClient = new SearchClient(options); ,但我们支持其他序列化程序,包括 System.Text.Json。如果有人要传递他们自己的设置——或者甚至想要默认设置——改变这可能是灾难性的。所以我很好奇:如果我们至少记录了这种行为变化(可能在 Newtonsoft.Json 类注释和/或 SearchClient 和相关方法上)以及如何保留以前的行为,那会有所帮助还是以其他方式满意吗?