DocumentDB 每次在大型分页提取中返回不同的结果计数
DocumentDB returning different result count every time on large paged fetch
问题
我正在尝试从 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
其中 none 与我预期的一样高。它们与我的预期相差 100 左右。
我排除了什么
这不是反序列化问题,因为我已经尝试更改
查询 select 一个不在结果集中的 ID 并获取它
很好。
这不是查询本身,因为我可以 运行 Azure 中的相同查询
门户网站的查询浏览器,还有一个 AND items.id = '...'
查找特定丢失的 ID 并 returns 它。
这不是我做分页的方式,因为我用过同样的方法
在其他地方进行较小的查询(~100 个结果)并且工作正常。
不是因为我跨越了数据中心边界,因为这个
在生产中也会发生。
我所怀疑的
可能是我的速率受到限制(我的两个 collections 是 S2),但我不确定为什么这会改变结果的数量,或者我将如何证明这一点。我可能会尝试将 collections 升级到 S3 以查看是否可以解决问题,但这对我来说不起作用 long-term.
除此之外,我非常感谢任何对可能发生的事情的洞察。谢谢!
编辑
我尝试升级 collections。没有变化。
编辑 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 并看到了类似的行为。
这是因为您使用的是惰性索引模式。顾名思义,惰性索引作为相对于写入的低优先级进程执行,并为查询提供 "eventually consistent results" 服务。
由于 DocumentDB 维护每个集合的多个副本(为了 HA 和性能),您的副本可能在为哪些文档编制索引方面领先或落后。
因为查询中的每个页面请求都由 client/gateway 为 load-balancing 随机路由,您可以看到 contain/miss 基于选择副本的结果。最终,当所有副本的索引都是最新的时,查询将 return 相同数量的结果。
如果您想要一致的查询结果,可以将集合切换为使用一致的索引模式。
问题
我正在尝试从 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
其中 none 与我预期的一样高。它们与我的预期相差 100 左右。
我排除了什么
这不是反序列化问题,因为我已经尝试更改 查询 select 一个不在结果集中的 ID 并获取它 很好。
这不是查询本身,因为我可以 运行 Azure 中的相同查询 门户网站的查询浏览器,还有一个
AND items.id = '...'
查找特定丢失的 ID 并 returns 它。这不是我做分页的方式,因为我用过同样的方法 在其他地方进行较小的查询(~100 个结果)并且工作正常。
不是因为我跨越了数据中心边界,因为这个 在生产中也会发生。
我所怀疑的
可能是我的速率受到限制(我的两个 collections 是 S2),但我不确定为什么这会改变结果的数量,或者我将如何证明这一点。我可能会尝试将 collections 升级到 S3 以查看是否可以解决问题,但这对我来说不起作用 long-term.
除此之外,我非常感谢任何对可能发生的事情的洞察。谢谢!
编辑
我尝试升级 collections。没有变化。
编辑 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 并看到了类似的行为。
这是因为您使用的是惰性索引模式。顾名思义,惰性索引作为相对于写入的低优先级进程执行,并为查询提供 "eventually consistent results" 服务。
由于 DocumentDB 维护每个集合的多个副本(为了 HA 和性能),您的副本可能在为哪些文档编制索引方面领先或落后。
因为查询中的每个页面请求都由 client/gateway 为 load-balancing 随机路由,您可以看到 contain/miss 基于选择副本的结果。最终,当所有副本的索引都是最新的时,查询将 return 相同数量的结果。
如果您想要一致的查询结果,可以将集合切换为使用一致的索引模式。