Рассмотрим следующий тип документа
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);
}