【问题标题】:Cosmos DB upsert from Azure Function - not updating, only insertingAzure Function 中的 Cosmos DB upsert - 不更新,只插入
【发布时间】:2021-12-30 22:07:53
【问题描述】:

当 POST(来自 Postman)时,我最终得到具有相同“_id”的重复文档。查看示例 herehere,我想知道我的问题是否是我的 Cosmos DB 实例中没有正确设置某些内容? 示例:

如果我将形状的颜色更新为橙色,我会得到另一个 键为 1 的文档,但我期望看到一个 键为 1 且形状为橙色的文档。

功能:

public static void Run(
  ILogger logger,
  [EventGridTrigger] EventGridEvent e,
  [CosmosDB(
      databaseName: "myDatabase",
      collectionName: "myCollection",
      ConnectionStringSetting = "COSMOS_CONNECTION_STRING")] out MyObject myObjectDocument
  )
  {
      logger.LogInformation("Event received {type} {subject}", e.EventType, e.Subject);

      myObjectDocument = JsonConvert.DeserializeObject<MyObject>(e.Data.ToString());

      logger.LogInformation(myObjectDocument.some.thing);
}

有效载荷:

[
  {   
      "topic": "Topic",
      "id": "1",   
      "eventType": "EventType",   
      "subject": "Subject",   
      "eventTime": "2012-08-10T21:04:07+00:00",
      "data" : {
        "id" : 1,
        "effectiveDate" : "2020-10-18 15:00:00",
        "shape" : {
            "_id" : "1000",
            "color" : "green",
            "name" : "square"
        }
      },
       "dataVersion": "2.0",   
       "metadataVersion": "1"
  }
]

编辑: 分区键是“id” Matias Quaranta 的回答和 cmets 成功了。另请注意,分区键必须是 string 而不是 int

【问题讨论】:

  • 请编辑以提供更多详细信息。例如:您的 Azure 函数实际上并没有做任何事情 - 不太清楚为什么包含它。而且您还没有包含有关 upsert 操作的任何详细信息。另外,您收藏的分区键是什么?
  • 我不明白,我以为 Cosmos DB 输出绑定处理了 Upsert 操作?还是仅适用于 Azure Functions 1.x?请参阅thisthisthis
  • _id 是 Mongo 的文档标识符。 Cosmos DB 的 SQL API 使用 id。你得到“重复”,因为你依赖_id匹配,这永远不会发生。

标签: c# azure-functions azure-cosmosdb


【解决方案1】:

_id 是 Mongo 的文档标识符。

Cosmos DB SQL API 使用 id。你得到了“重复”,因为你依赖于匹配 _id 的值,并且你可以拥有数百万个具有相同 _id 但不同 id 的文档。

SQL API 中的文档标识是id 的值和分区键。如果您的容器的分区键定义为/myPK(例如,您的可能不同),则文档的标识是idmyPK(或您的分区键定义中的任何一个)属性的值。在调用Upsert 时,如果存在具有相同idmyPK 值的文档,则会更新该文档,否则将创建一个带有正文的新文档。

【讨论】:

  • 感谢您的回复。所以我的分区键是_id,我正在阅读的是我需要更改它吗?如果正确,我可以将其更改为 id 还是会导致其他地方发生冲突?
  • 如果您的分区键是_id,那么您的文档标识就是id_id 的值。听起来根据您的帖子,您真的想使用 _id 作为文档的标识符。也许最好的做法是停止在您的文档中使用_id,而是使用id(因为它是您在概念上尝试做的事情)并让容器将/id 作为分区键。
  • 将分区键定义更改为/id,但仍发送您当前使用_id 作为文档标识符发送的相同有效负载不会解决您的问题。这个问题在您的设计中是概念性的,您在概念上尝试使用 _id 执行更新或创建,并且在 Mongo 数据库中运行良好,但在 Cosmos SQL API 上,您需要使用 id 来实现相同的目标。您的文档应包含id 而不是_id,事件网格数据应包含id,或者您可以生成与函数中_id 匹配的id 属性。
  • 如果您的文档没有 id 属性,Cosmos DB SDK 将自动生成它。这很可能意味着您的文档没有id 属性,并且它仍在传递_id
  • 看来我必须将分区键作为string 而不是code 传递。再次感谢您的回复!
【解决方案2】:

只有当 Id 和 分区键 相同时,cosmo DB 中的项目才能唯一。如果partition key不同,但Id相同,则item不唯一。

【讨论】:

    猜你喜欢
    • 2017-01-16
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多