【问题标题】:Cosmos DB Partial Document Update with Filter PredicateCosmos DB 部分文档更新与过滤谓词
【发布时间】:2022-11-14 13:22:30
【问题描述】:

我在更新存储在 Cosmos DB 中的 JSON 数据模型的部分文档时遇到了困难。本质上,我要做的是使用 PatchOperation.Set(也尝试过 PatchOperation.Replace)更新单个任务嵌套的 JSON(下面的示例),但不断收到可怕的“对象未设置为对象的实例”错误。在调用此方法之前,我进行查询以获取索引,以便我可以动态设置单个任务集和单个任务的索引,因为它可能位于不同的位置。我正在使用过滤谓词来获得正确的个人任务,因为不止一个人可以生活在个人任务集下。

{
"GroupTask": [
{
    "_type": null,
    "GroupTaskID": "GUID",
    "GroupTaskTitle": null,
    "GroupTaskDescription": null,
    "IndividualTaskSets": [
        {
            "SETID": "GUID",
            "CreatedBy": "",
            "CreatedDate": "0001-01-01T00:00:00",
            "IndividualTask": [
                {
                    "IndividualTaskID": "GUID",
                    "TaskStatus": "",
                    "TaskTitle": "",
                    "TaskType": "",
                    "TaskDescription": "",
                    "TaskNotes": "",
                    "Priority": "Normal",
                    "CreatedBy": "",
                    "CreatedDate": "0001-01-01T00:00:00"
                }
            ]
        }
    ]
}
],
"CaseID": "GUID",
"TenantID": "testtenant0004",
"id": "GUID",
"TaskID": "GUID"
}

下面是我正在使用的代码,我发送的过滤器谓词字符串如下“FROM Task t JOIN g in t.GroupTask JOIN its IN g.IndividualTask​​Sets JOIN it IN its.IndividualTask​​ WHERE it.IndividualTask​​ID =' " + itid + "'"

    public async Task<string> UpdateIT(ReturnTaskObject rto, IndividualTask updatedIT, string path)
    {

        try
        {
            PatchItemRequestOptions patchItemRequestOptions = new PatchItemRequestOptions
            {
                FilterPredicate = path
            };
            ItemResponse<IndividualTask> response = await container.PatchItemAsync<IndividualTask>
                (
                id: rto.id, 
                partitionKey: new Microsoft.Azure.Cosmos.PartitionKey(rto.taskid),
                patchOperations: new[] { PatchOperation.Set("/IndividualTaskSets/" + rto.individualtasksetidorindex + "/IndividualTask/" + rto.individualtaskidorindex + "/", updatedIT)},
                //tried this approach without the filter predicate thinking that was the issue but also yields the same error  
                //patchOperations: new[] { PatchOperation.Replace("/GroupTask/0/IndividualTaskSets/" + rto.individualtasksetidorindex + "/IndividualTask/" + rto.individualtaskidorindex + "/", updatedIT) }
                requestOptions: patchItemRequestOptions
                );
            string status = response.StatusCode.ToString();
            return status;
        }
        catch (Exception e)
        {
            return e.Message;
        }
    }

完整堆栈跟踪:

at CMaaS.Task.Service.DBUtil.UpdateIT(ReturnTaskObject rto, 
       IndividualTask updatedIT, String path)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at CMaaS.Task.Service.DBUtil.UpdateIT(ReturnTaskObject rto, 
  IndividualTask updatedIT, String path) at System.Dynamic.UpdateDelegates.UpdateAndExecute4[T0,T1,T2,T3,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)
   at CMaaS.Task.Function.FunctionTaskController.RunUpdateIndividualTaskSetAsync(HttpRequest req, ILogger log)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at CMaaS.Task.Function.FunctionTaskController.RunUpdateIndividualTaskSetAsync(HttpRequest req, ILogger log)
   at lambda_method149(Closure , FunctionTaskController , Object[] )
   at Microsoft.Azure.WebJobs.Host.Executors.TaskMethodInvoker`2.InvokeAsync(TReflected instance, Object[] arguments)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.InvokeAsync(Object instance, Object[] arguments)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object s)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread threadPoolThread)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
   at System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.<>c.<OutputCorrelationEtwEvent>b__6_0(Action innerContinuation, Task continuationIdTask)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke()
   at System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.RunAction(Object state)
   at System.Threading.QueueUserWorkItemCallbackDefaultContext.Execute()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
   at System.Threading.Thread.StartCallback()
}

【问题讨论】:

  • 你能粘贴整个堆栈跟踪吗?
  • @Sajeetharan 感谢您调查我的问题。上面添加了完整的堆栈跟踪。
  • 你得到这个工作了吗?我刚刚提供了 500 积分
  • 我需要知道如何在 cosmos 中可能存在或不存在的节点路径上执行 Set
  • 当您查询数据库时,会在数据库和 C# 类之间创建链接。更新使用查询中的链接。您以某种方式破坏了链接,或者您一开始就没有查询过数据库。创建对象的新实例是您可以断开链接的一种方式。

标签: c# azure-cosmosdb


【解决方案1】:

我相信你的路径错误,它应该是从根开始的。

像这样:

List<PatchOperation> patchOperations =  new List<PatchOperation>(); 

patchOperations.Add(PatchOperation.Set("/GroupTask/0/IndividualTaskSets/"+ rto.individualtasksetidorindex + "/IndividualTask/" + rto.individualtaskidorindex, updatedIT))

【讨论】:

    【解决方案2】:

    对于 set 操作,您只需在IndividualTaskSets大批

    patchOperations: new[] { PatchOperation.Set("/GroupTask/0/IndividualTaskSets/0/", YourObject)}
                 
    

    可以参考样例here

    关于你的第二个问题,我已经回答了here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      相关资源
      最近更新 更多