如何取消设置文件的字段?

时间:2013-12-31 12:31:36

标签: c# mongodb mongodb-.net-driver

我有一个完全动态的巨大表(没有映射到任何POCO)。它有多个字段,其中一个名为two。如何为ArchiveId设置为1的每个文档删除此字段?

我已尝试获取所有项目,然后保存每个项目,但它给了我错误。我怀疑db只是超时或者因为它正在工作和运行,因为我可以在之后获得记录。

请注意,我有超过100万条记录,我正在做的这种方法可能非常糟糕,但我不知道更好。

  

服务器实例localhost:27017不再连接。

我尝试了什么

public void DeleteFieldByArchiveId(int id, string field)
{
    var collection = _db.GetCollection("items");

    collection.Find(Query.EQ("ArchiveId", id))
        .ToList()
        .ForEach(x =>
        {
            x[field] = null;
            collection.Save(x);
        });
}

编辑(我需要的)

db.items.update({ArchiveId: 1}, {$unset: {two : ""}}, {multi: true})

基本上这是我想用C#mongo驱动程序实现的。我刚刚在RoboMongo中测试了这个查询,它在大约20秒内从1m数据库中删除了所有字段而没有超时。如何在C#mongo驱动程序中执行此查询?

3 个答案:

答案 0 :(得分:4)

以下是使用Unset类的静态Update方法执行查询的C#方式:

IMongoQuery query = Query.EQ("Activity", 1);         
UpdateBuilder ub = Update.Unset("two");
MongoUpdateOptions options = new MongoUpdateOptions {
    Flags = UpdateFlags.Multi
};
var updateResults = examples.Update(query, ub, options);

这导致:

query = { "Activity" : 1 }
update = { "$unset" : { "two" : 1 } }

(更新表达式中two的值并不重要per the documentation)。

完整示例:

using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;

var client = new MongoClient(); // connect to localhost
var server = client.GetServer();
var test = server.GetDatabase("test");
var examples = test.GetCollection("examples");

var query = Query.EQ("Activity", 1);         
var ub = Update.Unset("two");
var options = new MongoUpdateOptions {
    Flags = UpdateFlags.Multi
};
var updateResults = examples.Update(query, ub, options);
if (updateResults != null)
{                
    Console.WriteLine(updateResults);
}

答案 1 :(得分:3)

我在C#上非常生疏,但是如果你想按编辑说的那样做,那就试试吧:

MongoCollection<BsonDocument> items;
var query = new QueryDocument {
    { "ArchiveId", 1 }
};
var update = new UpdateDocument {
    { "$unset", new BsonDocument("two", "") }
};
BsonDocument update = items.Update(query, update, UpdateFlags.Multi);

供参考:http://docs.mongodb.org/ecosystem/tutorial/use-csharp-driver/#update-method

答案 2 :(得分:0)

您可能会用它溢出服务器。你有超过100万的记录,所以这可能是它。 尝试添加

System.Threading.Thread.Sleep(ms);

对于ms,你必须看看你需要多少。我会在50ms开始测试。

对于测试,我会使用:

for (int ms = 50; ms < 1001; ms++)
{
    try { DeleteFieldByArchiveId(id, field, ms); break; } catch { }
}

public void DeleteFieldByArchiveId(int id, string field, int TimeToWaitInMS)
{
    var collection = _db.GetCollection("items");

    collection.Find(Query.EQ("ArchiveId", id))
        .ToList()
        .ForEach(x =>
        {
            x[field] = null;
            collection.Save(x);
            System.Threading.Thread.Sleep(TimeToWaitInMS)
        });
}