首页 > 解决方案 > 为什么我的 Azure Cosmos 查询应该返回许多结果却返回空结果?

问题描述

我正在对我的 Cosmos 数据库实例运行查询,当我知道我应该得到一些结果时,我偶尔会得到 0 个结果。

        var options = new QueryRequestOptions()
        {
            MaxItemCount = 25
        };
        var query = @"
                    select c.id,c.callTime,c.direction,c.action,c.result,c.duration,c.hasR,c.hasV,c.callersIndexed,c.callers,c.files
                    from c
                    where
                    c.ownerId=@ownerId
                    and c.callTime>=@dateFrom
                    and c.callTime<=@dateTo
                    and (CONTAINS(c.phoneNums_s, @name)
                    or CONTAINS(c.names_s, @name)
                    or CONTAINS(c.xNums_s, @name))
                    order by c.callTime desc";
        var queryIterator = container.GetItemQueryIterator<CallIndex>(new QueryDefinition(query)
        .WithParameter("@ownerId", "62371255008")
        .WithParameter("@name", "harr")
        .WithParameter("@dateFrom", dateFrom) // 5/30/2020 5:00:00 AM +00:00
        .WithParameter("@dateTo", dateTo) // 8/29/2020 4:59:59 AM +00:00
        .WithParameter("@xnum", null), requestOptions: options, continuationToken: null);
        if (queryIterator.HasMoreResults)
        {
            var feed = queryIterator.ReadNextAsync().Result;
            model.calls = feed.ToList(); //feed.Resource is empty; feed.Count is 0;
            model.CosmosContinuationToken = feed.ContinuationToken; //feed.ContinuationToken is populated with a large token value, indicating that there are more results, even though this fetch returned 0 items.
            model.TotalRecords = feed.Count(); // 0
        }

如您所见,即使我收到 0 个结果,延续令牌表明在第一次请求之后还有更多数据。而且,在直接在数据库(Azure 门户中的数据资源管理器)中直观地检查数据后,我看到了应该匹配的记录,但在此查询中找不到它们。为了进一步测试,几秒钟后我运行了相同的查询,并收到了结果:

        var query = @"
                    select c.id,c.callTime,c.direction,c.action,c.result,c.duration,c.hasR,c.hasV,c.callersIndexed,c.callers,c.files
                    from c
                    where
                    c.ownerId=@ownerId
                    and c.callTime>=@dateFrom
                    and c.callTime<=@dateTo
                    and (CONTAINS(c.phoneNums_s, @name)
                    or CONTAINS(c.names_s, @name)
                    or CONTAINS(c.xNums_s, @name))
                    order by c.callTime desc";
        var queryIterator = container.GetItemQueryIterator<CallIndex>(new QueryDefinition(query)
        .WithParameter("@ownerId", "62371255008")
        .WithParameter("@name", "harr")
        .WithParameter("@dateFrom", dateFrom) // 5/30/2020 5:00:00 AM +00:00
        .WithParameter("@dateTo", dateTo) // 8/29/2020 4:59:59 AM +00:00
        .WithParameter("@xnum", null), requestOptions: options, continuationToken: null);
        if (queryIterator.HasMoreResults)
        {
            var feed = queryIterator.ReadNextAsync().Result;
            model.calls = feed.ToList(); //feed.Resource has 25 items; feed.Count is 25;
            model.CosmosContinuationToken = feed.ContinuationToken; //feed.ContinuationToken is populated, but it is considerably smaller than the token I received from the first request.
            model.TotalRecords = feed.Count(); // 25
        }

这是与以前一样的确切查询,但这次feed给了我预期的结果。这已经发生了不止一次,并且断断续续地继续发生。什么给了这个?这是 Azure Cosmos 中的错误吗?如果是这样,这似乎是一个严重的错误,它破坏了 Cosmos(以及一般数据库)的核心功能。

或者,这是预期的吗?是否有可能在第一个查询中,我需要继续,ReadNextAsync直到我使用延续令牌获得一些结果?

感谢您提供任何帮助,因为这破坏了我的应用程序中非常基本的功能。

另外,我想补充一点,从查询返回的数据在我第一次查询尝试和第二次查询尝试之间没有新添加。这些数据已经存在了一段时间。

标签: c#azure-cosmosdb

解决方案


您的代码是正确的,您应该排空查询检查HasMoreResults(尽管我会更改.Resultwithawait以避免可能的死锁)。跨分区查询中可能发生的情况是,如果检查结果的初始分区没有,您可能会得到一些空白页面。

有时即使在未来页面上有结果,查询也可能有空页面。原因可能是:

  • SDK 可能正在执行多个网络调用。
  • 查询可能需要很长时间才能检索文档。

参考:https ://docs.microsoft.com/azure/cosmos-db/troubleshoot-query-performance#common-sdk-issues


推荐阅读