如何使用MongoDB API删除Azure CosmosDB中分区集合中的许多文档 [英] How to delete many documents in a partitioned collection in Azure CosmosDB using MongoDB API

查看:54
本文介绍了如何使用MongoDB API删除Azure CosmosDB中分区集合中的许多文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下文档类型

class Info
{
    public string Id { get; set; }
    public string UserId { get; set; }  // used as partition key
    public DateTime CreatedAt { get; set; }
}

我已经用这个创建了一个收藏集

I've created a collection using this

var bson = new BsonDocument
{
    { "shardCollection", "mydb.userInfo" },
    { "key", new BsonDocument(shardKey, "hashed") }
};
database.RunCommand(new BsonDocumentCommand<BsonDocument>(bson));

要删除所有早于特定日期的文档,我尝试过

To delete all documents that are older than a certain date, I tried this

collection.DeleteManyAsync(t => t.CreatedAt >= date);

但是此操作失败,并显示Command delete failed: query in command must target a single shard key.我的问题是,如何有效地删除多个分区中的这些文档?在这种情况下,我不是在寻找如何选择分区键的答案.我认为在某些情况下,我不得不在所有分区上运行修改查询.

But this fails with Command delete failed: query in command must target a single shard key. My question is, how should I efficently delete these documents across multiple partitions? I'm not looking for answers how to choose the partition key in this case. I think that there will be always cases where I have to run modifiying queries across all partitions.

我可以先使用collection.Find(t => t.CreatedAt >= date)查询文档,然后为每组分区键运行一个DeleteManyAsync(t => idsInThatPartition.Contains(t.Id) && t.UserId == thatPartitionKey),但是我真的希望有更好的方法.示例代码:

I could first query for documents with collection.Find(t => t.CreatedAt >= date) and then run a DeleteManyAsync(t => idsInThatPartition.Contains(t.Id) && t.UserId == thatPartitionKey) for each group of partition key, but I really hope that there is a better way. Example code:

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);
}

推荐答案

我不了解特定于C#语法的问题,但是我设法通过MongoDB批量操作解决了此问题.

I don't know about C# syntax specific but I managed to work around this issue with a MongoDB Bulk Operation.

这个解决方案远非完美,但是我想解决这个问题的唯一方法.

this solution is far from perfect but is the only way I could think to solve this.

这是我如何在Node.js上实现此示例:

this is an example of how I implemented this on Nodejs:

//First find all your document you want to Update/Delete
const res = await model.find(query).lean().exec()

//Initialize bulk operation object
var bulk = model.collection.initializeUnorderedBulkOp();

//Iterate the results
res.forEach((item: any) => {

    //Find your document with your shared key ( my shared key is the document _id)
    bulk.find({ _id: item._id }).removeOne();
})

//Check if should excute the bulk operation
if (bulk.length > 0)
    //Execute all operations at once
    return await bulk.execute();

对MongoDB批量操作的引用 https://docs.mongodb.com/manual /reference/method/Bulk/

Reference to MongoDB bulk operation https://docs.mongodb.com/manual/reference/method/Bulk/

这篇关于如何使用MongoDB API删除Azure CosmosDB中分区集合中的许多文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆