【问题标题】:Handling reads of Cosmos DB container with multiple types?处理具有多种类型的 Cosmos DB 容器的读取?
【发布时间】:2021-06-13 23:47:42
【问题描述】:

我想将几种不同的对象类型存储在一个 Cosmos DB 容器中,因为它们都在逻辑上分组并且可以按时间戳一起读取以避免额外的 HTTP 调用。

但是,Cosmos DB 客户端 API 似乎没有提供一种简单的方法来执行多种类型的读取。到目前为止我发现的最佳解决方案是编写自己的 CosmosSerializer 和 JsonConverter,但感觉很笨拙:https://thomaslevesque.com/2019/10/15/handling-type-hierarchies-in-cosmos-db-part-2/

是否有更优雅的方式将不同类型的项目读取到共享基类,以便我以后可以转换它们,还是我必须接受打击?

谢谢!

【问题讨论】:

  • 如果你有一个 JSON 文本文件而不是对 Cosmos 的查询,问题会不会是一样的?在反序列化时,您似乎总是需要选择所需的具体类型,否则需要进行第二次反序列化操作。
  • 更优雅?这对你来说代表着什么。客观地说?
  • @TylerH 更容易维护,例如。拥有自己的序列化器和转换器意味着更多的维护工作。如果参考实现发生变化,我需要 1) 了解它并 2) 采用这些变化。
  • @NoahStahl 当然可以,但我希望这作为 Cosmos 中数据访问的一种常见模式,会围绕它构建更多的糖。
  • 我预计原因是如果您尝试动态处理项目而不是直接反序列化为预期类型,则会影响性能。就个人而言,我使用类型作为分区键的一部分,并且大部分时间都围绕强类型查询进行设计。

标签: azure-cosmosdb azure-cosmosdb-sqlapi


【解决方案1】:

我这样做的方法是将 ItemQueryIterator 和 FeedResponse 对象创建为动态对象,并最初以无类型方式读取它们,因此我可以检查一个“type”属性,该属性告诉我要反序列化为哪种类型的对象。

在此示例中,我有一个容器,其中包含我的客户数据及其所有销售订单。代码如下所示。

        string sql = "SELECT * from c WHERE c.customerId = @customerId";

        FeedIterator<dynamic> resultSet = container.GetItemQueryIterator<dynamic>(
            new QueryDefinition(sql)
            .WithParameter("@customerId", customerId),
            requestOptions: new QueryRequestOptions 
            { 
                PartitionKey = new PartitionKey(customerId) 
            });

        CustomerV4 customer = new CustomerV4();
        List<SalesOrder> orders = new List<SalesOrder>();

        while (resultSet.HasMoreResults)
        {
            //dynamic response. Deserialize into POCO's based upon "type" property
            FeedResponse<dynamic> response = await resultSet.ReadNextAsync();
            foreach (var item in response)
            {
                if (item.type == "customer")
                {
                    customer = JsonConvert.DeserializeObject<CustomerV4>(item.ToString());
                    
                }
                else if (item.type == "salesOrder")
                {
                    orders.Add(JsonConvert.DeserializeObject<SalesOrder>(item.ToString()));
                }
            }
        }

【讨论】:

  • 知道反序列化为动态优先是否有任何性能影响?
  • 我不知道。我无法想象它会很多,而且这种模式是处理容器中多个实体的典型模式。
猜你喜欢
  • 2021-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
  • 2016-02-22
  • 1970-01-01
  • 2014-12-11
相关资源
最近更新 更多