为什么当HasMoreResults为True时,CosmosDB FeedResponse不包含任何结果

问题描述 投票:1回答:1

即使ExecuteNextAsync返回true,IDocumentQuery上的HasMoreResults似乎也没有返回任何结果。随后对ExecuteNextAsync的调用意外返回数据。此外,ToList()上的IQueryable一致地返回数据。

这是生产代码中的行为变化,正确运行了一年多,这意味着ExecuteNextAsync之前可靠地返回结果。

我已经将我的生产代码简化为可重复的测试用例。查询组合似乎对ExecuteNextAsync的行为有影响(即在返回结果之前进行一次或多次调用)。例如,如果我执行id + partitionKey查找,它会按预期工作。

相关依赖:

  • <TargetFramework>netcoreapp2.0</TargetFramework>
  • <PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.3.0" />

我研究了以下没有帮助的内容:

这是一个演示该问题的最小测试:

using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Newtonsoft.Json;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Program.Run(args).GetAwaiter().GetResult();
        }

        static string endpointUrl = "xxxxx";
        static string authKeyOrResourceToken = "xxxxx";
        static Uri collectionUri = UriFactory.CreateDocumentCollectionUri("xxxxx", "xxxxx");

        static async Task Run(string[] args)
        {
            ConnectionPolicy connectionPolicy = new ConnectionPolicy();
            DocumentClient client = new DocumentClient(new Uri(endpointUrl), authKeyOrResourceToken, connectionPolicy, ConsistencyLevel.BoundedStaleness);

            await Program.Test(client);
        }

        public static async Task Test(DocumentClient client)
        {
            FeedOptions feedOptions = new FeedOptions()
            {
                EnableCrossPartitionQuery = true,
                MaxDegreeOfParallelism = -1,
                MaxBufferedItemCount = 1,
                MaxItemCount = 1,
                PopulateQueryMetrics = true,
            };

            StringBuilder sql = new StringBuilder();
            sql.AppendLine(" SELECT c.editionBudgetOrderGroupID, c.items, c.artifactType, c.level, c.editionID, c.sectionID, c.parentContentRef");
            sql.AppendLine(" FROM c ");
            sql.AppendLine(" JOIN items IN c.items ");
            sql.AppendLine(" WHERE ");
            sql.AppendLine("     c.artifactType = @artifactType ");
            sql.AppendLine("     AND items.contentID = @childContentId ");
            sql.AppendLine("     AND c.level = @level");
            sql.AppendLine("     AND c.tenant = @tenantId");

            SqlParameterCollection sqlParams = new SqlParameterCollection
            {
                new SqlParameter("@artifactType", "EditionBudgetOrderGroup"),
                new SqlParameter("@tenantId", "xxx"),
                new SqlParameter("@childContentId", "xxxxx"),
                new SqlParameter("@level", "ContentItemLevel")
            };

            SqlQuerySpec sqlSpec = new SqlQuerySpec
            {
                QueryText = sql.ToString(),
                Parameters = sqlParams,
            };
            // this is ok
            Document thisIsOk1 = client.CreateDocumentQuery<Document>(
                collectionUri,
                sqlSpec,
                feedOptions).ToList().FirstOrDefault();

            // this is ok
            Document thisIsOk2 = client.CreateDocumentQuery<Document>(
                collectionUri,
                sqlSpec,
                feedOptions).AsEnumerable().FirstOrDefault();


            // This is normally called by the calling method, value returned is null
            IDocumentQuery<Document> result = client.CreateDocumentQuery<Document>(
                collectionUri,
                sqlSpec,
                feedOptions).AsDocumentQuery();

            Console.WriteLine($"result.HasMoreResults: {result.HasMoreResults}");

            FeedResponse<Document> feedResponse1 = await result.ExecuteNextAsync<Document>();
            IList<Document> thisIsNullList = feedResponse1.ToList();
            Console.WriteLine($"thisIsNullList?.Count  : {thisIsNullList?.Count}");

            Document thisIsNull = feedResponse1.FirstOrDefault();

            // this is ok - calling ExecuteNextAsync causes expected result
            FeedResponse<Document> feedResponse2 = await result.ExecuteNextAsync<Document>();
            Document thisIsOk3 = feedResponse2.FirstOrDefault();


            Console.WriteLine($"thisIsOk1 == null  : {thisIsOk1 == null}");
            Console.WriteLine($"thisIsOk2 == null  : {thisIsOk2 == null}");
            Console.WriteLine($"thisIsNull == null : {thisIsNull == null}");
            Console.WriteLine($"thisIsOk3 == null  : {thisIsOk3 == null}");

            string metrics1 = JsonConvert.SerializeObject(feedResponse1.QueryMetrics, Formatting.Indented);
            string metrics2 = JsonConvert.SerializeObject(feedResponse2.QueryMetrics, Formatting.Indented);

            Console.WriteLine($"feedResponse1.QueryMetrics: {metrics1}");
            Console.WriteLine($"feedResponse2.QueryMetrics: {metrics2}");
        }
    }
}

result.HasMoreResults: True
thisIsNullList?.Count  : 0

我期待thisIsNull有一个值,因为HasMoreResults是True。

thisIsOk1 == null  : False
thisIsOk2 == null  : False
thisIsNull == null : True
thisIsOk3 == null  : False

以下是第一个和第二个ExecuteNextAsync操作的查询指标。有时第二个操作没有像下面那样的指标,有时候它没有填充。

feedResponse1.QueryMetrics: {
  "1": {
    "TotalTime": "00:00:00.0017400",
    "RetrievedDocumentCount": 0,
    "RetrievedDocumentSize": 0,
    "OutputDocumentCount": 0,
    "QueryPreparationTimes": {
      "CompileTime": "00:00:00.0001300",
      "LogicalPlanBuildTime": "00:00:00.0000700",
      "PhysicalPlanBuildTime": "00:00:00.0001400",
      "QueryOptimizationTime": "00:00:00.0000100"
    },
    "QueryEngineTimes": {
      "IndexLookupTime": "00:00:00.0011200",
      "DocumentLoadTime": "00:00:00",
      "WriteOutputTime": "00:00:00",
      "RuntimeExecutionTimes": {
        "SystemFunctionExecutionTime": "00:00:00",
        "UserDefinedFunctionExecutionTime": "00:00:00",
        "TotalTime": "00:00:00.0000300"
      }
    },
    "Retries": 0,
    "ClientSideMetrics": {
      "Retries": 0,
      "RequestCharge": 11.83,
      "FetchExecutionRanges": [
        {
          "ActivityId": "660e25e9-0904-4f97-a627-f836422151f3",
          "StartTime": "2019-05-01T19:38:07.0354836Z",
          "EndTime": "2019-05-01T19:38:07.0642583Z",
          "PartitionId": "1",
          "NumberOfDocuments": 0,
          "RetryCount": 0
        }
      ],
      "PartitionSchedulingTimeSpans": [
        {
          "Item1": "1",
          "Item2": {
            "NumPreemptions": 1,
            "TurnaroundTime": "00:00:00.0289540",
            "ResponseTime": "00:00:00.0000617",
            "RunTime": "00:00:00.0287753",
            "WaitTime": "00:00:00.0001791"
          }
        }
      ]
    },
    "IndexHitRatio": 1.0
  },
  "2": {
    "TotalTime": "00:00:00.0016100",
    "RetrievedDocumentCount": 1,
    "RetrievedDocumentSize": 1356,
    "OutputDocumentCount": 1,
    "QueryPreparationTimes": {
      "CompileTime": "00:00:00.0001300",
      "LogicalPlanBuildTime": "00:00:00.0000800",
      "PhysicalPlanBuildTime": "00:00:00.0001500",
      "QueryOptimizationTime": "00:00:00.0000200"
    },
    "QueryEngineTimes": {
      "IndexLookupTime": "00:00:00.0009200",
      "DocumentLoadTime": "00:00:00.0000300",
      "WriteOutputTime": "00:00:00",
      "RuntimeExecutionTimes": {
        "SystemFunctionExecutionTime": "00:00:00",
        "UserDefinedFunctionExecutionTime": "00:00:00",
        "TotalTime": "00:00:00.0000500"
      }
    },
    "Retries": 0,
    "ClientSideMetrics": {
      "Retries": 0,
      "RequestCharge": 12.8,
      "FetchExecutionRanges": [
        {
          "ActivityId": "3fc13562-1f3a-4636-ac54-492d01040dcb",
          "StartTime": "2019-05-01T19:38:07.035552Z",
          "EndTime": "2019-05-01T19:38:07.0634899Z",
          "PartitionId": "2",
          "NumberOfDocuments": 1,
          "RetryCount": 0
        }
      ],
      "PartitionSchedulingTimeSpans": [
        {
          "Item1": "2",
          "Item2": {
            "NumPreemptions": 1,
            "TurnaroundTime": "00:00:00.0281628",
            "ResponseTime": "00:00:00.0000935",
            "RunTime": "00:00:00.0279391",
            "WaitTime": "00:00:00.0002242"
          }
        }
      ]
    },
    "IndexHitRatio": 1.0
  }
}
feedResponse2.QueryMetrics: {}
azure asp.net-core azure-cosmosdb
1个回答
1
投票

我已经确定这是SDK中的一个错误。降级到Microsoft.Azure.DocumentDB.Core 2.2.2解决了这个问题。 thisIsNull不再等于null。 SDK问题似乎已在2.2.3中引入,也是2.3.0中的一个问题

<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.2.2" />

这是更新后的输出:

result.HasMoreResults: True
thisIsNullList?.Count  : 1
thisIsOk1 == null  : False
thisIsOk2 == null  : False
thisIsNull == null : False
thisIsOk3 == null  : False
feedResponse1.QueryMetrics: {
  "2": {
    "TotalTime": "00:00:00.0016100",
    "RetrievedDocumentCount": 1,
    "RetrievedDocumentSize": 1356,
    "OutputDocumentCount": 1,
    "QueryPreparationTimes": {
      "CompileTime": "00:00:00.0002000",
      "LogicalPlanBuildTime": "00:00:00.0000600",
      "PhysicalPlanBuildTime": "00:00:00.0000900",
      "QueryOptimizationTime": "00:00:00.0000100"
    },
    "QueryEngineTimes": {
      "IndexLookupTime": "00:00:00.0009300",
      "DocumentLoadTime": "00:00:00.0000300",
      "WriteOutputTime": "00:00:00",
      "RuntimeExecutionTimes": {
        "SystemFunctionExecutionTime": "00:00:00",
        "UserDefinedFunctionExecutionTime": "00:00:00",
        "TotalTime": "00:00:00.0000500"
      }
    },
    "Retries": 0,
    "ClientSideMetrics": {
      "Retries": 0,
      "RequestCharge": 12.8,
      "FetchExecutionRanges": [
        {
          "ActivityId": "cca905f5-cb83-49a0-a964-de56430725d1",
          "StartTime": "2019-05-01T21:35:53.0457606Z",
          "EndTime": "2019-05-01T21:35:53.0713622Z",
          "PartitionId": "2",
          "NumberOfDocuments": 1,
          "RetryCount": 0
        }
      ],
      "PartitionSchedulingTimeSpans": [
        {
          "Item1": "2",
          "Item2": {
            "NumPreemptions": 1,
            "TurnaroundTime": "00:00:00.0259268",
            "ResponseTime": "00:00:00.0002747",
            "RunTime": "00:00:00.0256023",
            "WaitTime": "00:00:00.0003246"
          }
        }
      ]
    },
    "IndexHitRatio": 1.0
  },
  "1": {
    "TotalTime": "00:00:00.0017500",
    "RetrievedDocumentCount": 0,
    "RetrievedDocumentSize": 0,
    "OutputDocumentCount": 0,
    "QueryPreparationTimes": {
      "CompileTime": "00:00:00.0001200",
      "LogicalPlanBuildTime": "00:00:00.0000900",
      "PhysicalPlanBuildTime": "00:00:00.0001300",
      "QueryOptimizationTime": "00:00:00.0000100"
    },
    "QueryEngineTimes": {
      "IndexLookupTime": "00:00:00.0010900",
      "DocumentLoadTime": "00:00:00",
      "WriteOutputTime": "00:00:00",
      "RuntimeExecutionTimes": {
        "SystemFunctionExecutionTime": "00:00:00",
        "UserDefinedFunctionExecutionTime": "00:00:00",
        "TotalTime": "00:00:00.0000200"
      }
    },
    "Retries": 0,
    "ClientSideMetrics": {
      "Retries": 0,
      "RequestCharge": 11.83,
      "FetchExecutionRanges": [
        {
          "ActivityId": "fded90c2-dacb-468e-97ad-58ddf28cb0eb",
          "StartTime": "2019-05-01T21:35:53.0457474Z",
          "EndTime": "2019-05-01T21:35:53.0701024Z",
          "PartitionId": "1",
          "NumberOfDocuments": 0,
          "RetryCount": 0
        }
      ],
      "PartitionSchedulingTimeSpans": [
        {
          "Item1": "1",
          "Item2": {
            "NumPreemptions": 1,
            "TurnaroundTime": "00:00:00.0246889",
            "ResponseTime": "00:00:00.0002799",
            "RunTime": "00:00:00.0243563",
            "WaitTime": "00:00:00.0003328"
          }
        }
      ]
    },
    "IndexHitRatio": 1.0
  }
}
feedResponse2.QueryMetrics: {
  "1": {
    "TotalTime": "00:00:00.0020400",
    "RetrievedDocumentCount": 0,
    "RetrievedDocumentSize": 0,
    "OutputDocumentCount": 0,
    "QueryPreparationTimes": {
      "CompileTime": "00:00:00.0001200",
      "LogicalPlanBuildTime": "00:00:00.0001400",
      "PhysicalPlanBuildTime": "00:00:00.0001100",
      "QueryOptimizationTime": "00:00:00.0000100"
    },
    "QueryEngineTimes": {
      "IndexLookupTime": "00:00:00.0013600",
      "DocumentLoadTime": "00:00:00",
      "WriteOutputTime": "00:00:00",
      "RuntimeExecutionTimes": {
        "SystemFunctionExecutionTime": "00:00:00",
        "UserDefinedFunctionExecutionTime": "00:00:00",
        "TotalTime": "00:00:00.0000100"
      }
    },
    "Retries": 0,
    "ClientSideMetrics": {
      "Retries": 0,
      "RequestCharge": 11.83,
      "FetchExecutionRanges": [
        {
          "ActivityId": "8e395b01-f970-4183-84fe-45f44f0ec1a5",
          "StartTime": "2019-05-01T21:36:05.1121303Z",
          "EndTime": "2019-05-01T21:36:05.1376982Z",
          "PartitionId": "1",
          "NumberOfDocuments": 0,
          "RetryCount": 0
        }
      ],
      "PartitionSchedulingTimeSpans": [
        {
          "Item1": "1",
          "Item2": {
            "NumPreemptions": 1,
            "TurnaroundTime": "00:00:00.0260265",
            "ResponseTime": "00:00:00.0003902",
            "RunTime": "00:00:00.0255689",
            "WaitTime": "00:00:00.0004579"
          }
        }
      ]
    },
    "IndexHitRatio": 1.0
  },
  "2": {
    "TotalTime": "00:00:00.0019200",
    "RetrievedDocumentCount": 1,
    "RetrievedDocumentSize": 1356,
    "OutputDocumentCount": 1,
    "QueryPreparationTimes": {
      "CompileTime": "00:00:00.0001700",
      "LogicalPlanBuildTime": "00:00:00.0001100",
      "PhysicalPlanBuildTime": "00:00:00.0001700",
      "QueryOptimizationTime": "00:00:00.0000100"
    },
    "QueryEngineTimes": {
      "IndexLookupTime": "00:00:00.0011200",
      "DocumentLoadTime": "00:00:00.0000400",
      "WriteOutputTime": "00:00:00",
      "RuntimeExecutionTimes": {
        "SystemFunctionExecutionTime": "00:00:00",
        "UserDefinedFunctionExecutionTime": "00:00:00",
        "TotalTime": "00:00:00.0000400"
      }
    },
    "Retries": 0,
    "ClientSideMetrics": {
      "Retries": 0,
      "RequestCharge": 12.8,
      "FetchExecutionRanges": [
        {
          "ActivityId": "7a5d1e18-aa15-4fa3-b68f-828dae99cd39",
          "StartTime": "2019-05-01T21:36:05.1121553Z",
          "EndTime": "2019-05-01T21:36:05.1377267Z",
          "PartitionId": "2",
          "NumberOfDocuments": 1,
          "RetryCount": 0
        }
      ],
      "PartitionSchedulingTimeSpans": [
        {
          "Item1": "2",
          "Item2": {
            "NumPreemptions": 1,
            "TurnaroundTime": "00:00:00.0259876",
            "ResponseTime": "00:00:00.0003792",
            "RunTime": "00:00:00.0255721",
            "WaitTime": "00:00:00.0004157"
          }
        }
      ]
    },
    "IndexHitRatio": 1.0
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.