【发布时间】:2019-03-05 11:10:51
【问题描述】:
考虑以下文档类型
class Info
{
public string Id { get; set; }
public string UserId { get; set; } // used as partition key
public DateTime CreatedAt { get; set; }
}
我用这个创建了一个集合
var bson = new BsonDocument
{
{ "shardCollection", "mydb.userInfo" },
{ "key", new BsonDocument(shardKey, "hashed") }
};
database.RunCommand(new BsonDocumentCommand<BsonDocument>(bson));
要删除所有早于某个日期的文档,我试过这个
collection.DeleteManyAsync(t => t.CreatedAt >= date);
但是Command delete failed: query in command must target a single shard key. 失败了我的问题是,我应该如何跨多个分区有效地删除这些文档?在这种情况下,我不是在寻找如何选择分区键的答案。我认为总会有我必须跨所有分区运行修改查询的情况。
我可以先用collection.Find(t => t.CreatedAt >= date) 查询文档,然后为每组分区键运行DeleteManyAsync(t => idsInThatPartition.Contains(t.Id) && t.UserId == thatPartitionKey),但我真的希望有更好的方法。示例代码:
var affectedPartitions = await collection.Aggregate()
.Match(i => i.CreatedAt >= date)
.Group(i => i.UserId, group => new { Key = group.Key })
.ToListAsync();
foreach (var partition in affectedPartitions)
{
await collection.DeleteManyAsync(
i => i.CreatedAt >= date && i.UserId == partition.Key);
}
【问题讨论】:
-
这可能是另一个与实现相关的“Cosmos DB”特定事物。 MongoDB 不会针对“多”或“多”变体发出该投诉。仅当您使用
updateOne()或deleteOne()并且不包含分片键时,才会从 MongoDB 引发错误。这里最合理的回应是,因为这不是 MongoDB,所以不要期望它会像 MongoDB 一样做所有事情。 -
仅供参考:Single Document Modification Operations in Sharded Collections。当然,github.com/MicrosoftDocs/azure-docs/issues/12292 但既然你已经在那里发帖了,你应该知道这一点。简而言之,MongoDB 本身按设计工作。
-
@NeilLunn 感谢您的评论。当然,这是一个 cosmosdb 问题。我已经知道 MongoDB 中的“多”事物,但在 cosmosdb 中找不到如何做到这一点。也许 MongoDB 标记具有误导性......这个问题更多的是关于解决对跨分区查询的缺失支持。
-
我明白这一点,而且我的 cmets 可能更适合“其他读者”而不是您自己。我不会抱太大希望,主要是因为我自己和其他人已经“清理”了各种 CosmosDB 问题,这些问题归结为 MongoDB 实际所做的不受支持的事情。基本上这里有一个模板答案,它基本上说:“CosmosDB 不是 MongoDB,所以不要指望它会一样工作”。我不确定是否有本地 API 方式来进行查询,但很明显 MongoDB API 兼容性在这里没有正确完成。
标签: c# mongodb azure azure-cosmosdb mongodb-.net-driver