DocumentDB每次在大型分页抓取时返回不同的结果计数

时间:2015-12-30 19:15:25

标签: c# azure azure-cosmosdb

问题

我正在尝试从docdb中提取大约20,000个文档。为了减少我提取的金额,我只是提取文件的ID。我正在翻阅结果,当我在完成后建立一个列表时,我发现结果的数量发生了变化(而且它们都错了!)。它没有得到它应该得到的所有结果。目前没有其他流程涉及数据。

以下是我如何查询的想法:

var sql = new SqlQuerySpec(@"SELECT items.id FROM items WHERE items.foo = @bar")
{
    Parameters = new SqlParameterCollection { new SqlParameter("@bar", bar) }
};

var feedOptions = new FeedOptions { MaxItemCount = 2000 };
var query = this.Context.Client.CreateDocumentQuery<Foo>(dbSelfLink, sql, feedOptions).AsDocumentQuery();

var ids = new List<string>();

while (query.HasMoreResults)
{
    var page = await query.ExecuteNextAsync<Foo>().ConfigureAwait(false);
    ids.AddRange(page.AsEnumerable());
}

我在调试时运行了三次并获得了三个不同的ID计数:

19,323
19,321
19,327

这些都没有我想象的那么高。它们在我预期的100左右之内。

我排除了什么

  • 这不是反序列化问题,因为我尝试过更改 查询以选择不在结果集中的ID并抓取它 细

  • 这不是查询本身,因为我可以在Azure中运行相同的查询 门户网站的查询资源管理器附加AND items.id = '...' 寻找特定的缺失ID并将其返回。

  • 这不是我正在进行分页的方式,因为我使用了同样的方法 在其他地方进行较小的查询(约100个结果)并且工作正常。

  • 这不是因为我正在越过数据中心边界 也在生产中发生。

我怀疑

可能是我的速度有限(我的两个系列是S2),但我不确定为什么会改变结果的数量,或者我将如何证明这一点。我可能会尝试将集合升级到S3以查看是否可以解决问题,但这对我来说不会长期有效。

除此之外,我真的很感激任何有关可能发生的事情的见解。谢谢!

修改

我尝试升级收藏品。没有变化。

编辑2以回复评论

是的,我们正在使用懒惰的索引......我开始怀疑这是否是罪魁祸首但不确定为什么会导致我们没有获得所有记录。如果这需要改变,那可能没问题,因为索引最初是在没有太多考虑的情况下完成的(并且它使用的是旧格式,你可以在这里看到)。以下是索引政策:

{
  "indexingMode": "Lazy",
  "automatic": true,
  "includedPaths": [
    {
      "path": "/",
      "indexes": [
        {
          "kind": "Hash",
          "dataType": "Number",
          "precision": 3
        },
        {
          "kind": "Hash",
          "dataType": "String",
          "precision": 3
        }
      ]
    },
    {
      "path": "/\"_ts\"/?",
      "indexes": [
        {
          "kind": "Range",
          "dataType": "Number",
          "precision": 6
        },
        {
          "kind": "Hash",
          "dataType": "String",
          "precision": 3
        }
      ]
    }
  ],
  "excludedPaths": []
}

关于MaxItemCount,我也试过-1并看到了类似的行为。

1 个答案:

答案 0 :(得分:2)

这是因为您正在使用延迟索引模式。顾名思义,延迟索引是作为相对于写入的低优先级进程执行的,并提供最终一致的结果&#34;查询。

由于DocumentDB维护着每个集合的多个副本(对于HA和性能),因此您可能拥有在索引哪些文档方面更先进或落后的副本。

由于客户端/网关随机路由查询中的每个页面请求以进行负载平衡,因此您可以根据选择的副本查看可能包含/遗漏结果的结果。最终,当索引在所有副本上都是最新的时,查询将返回相同数量的结果。

如果您想要一致的查询结果,可以切换集合以使用一致的索引模式。