C# 在MongoDb中,如何在数组属性中的对象上设置值?

C# 在MongoDb中,如何在数组属性中的对象上设置值?,c#,mongodb,mongodb-.net-driver,C#,Mongodb,Mongodb .net Driver,我的目标是在文档数组中的特定对象上放置一个“deleted at”时间戳 如果文档看起来像这样: { "subdoc": [ { "key": 1, "value": "abc", "isActive": true }, { "key":5, "value": "ade", "isActive

我的目标是在文档数组中的特定对象上放置一个“deleted at”时间戳

如果文档看起来像这样:

{   
    "subdoc": [
        {
            "key": 1,
            "value": "abc",
            "isActive": true
        },
        {
            "key":5,
            "value": "ade",
            "isActive":true
        }
    ]
}
{   
    "subdoc": [
        {
            "key": 1,
            "value": "abc",
            "isActive": true
        },
        {
            "key":5,
            "value": "ade",
            "isActive": false,
            "deletedAt": Timestamp(1425911075,1)
        }
    ]
}
// find
{
    "subdoc.key":"2",
    "subdoc.value":"ade"
}
// update
{   
    "$currentDate": {
        "subdoc.$.deleteAt": {
            "$type": "timestamp"
        }
    }
}
我希望能够说“查找subdoc.key==5和subdoc.value==ade的文档”;将subdoc.isActive设置为false,并将subdoc.deleteAt设置为current db timestamp。生成的文档如下:

{   
    "subdoc": [
        {
            "key": 1,
            "value": "abc",
            "isActive": true
        },
        {
            "key":5,
            "value": "ade",
            "isActive":true
        }
    ]
}
{   
    "subdoc": [
        {
            "key": 1,
            "value": "abc",
            "isActive": true
        },
        {
            "key":5,
            "value": "ade",
            "isActive": false,
            "deletedAt": Timestamp(1425911075,1)
        }
    ]
}
// find
{
    "subdoc.key":"2",
    "subdoc.value":"ade"
}
// update
{   
    "$currentDate": {
        "subdoc.$.deleteAt": {
            "$type": "timestamp"
        }
    }
}
这可行吗

更新:在进一步审查mongo文档之后,使用“$(更新)”操作符似乎是可行的。这就得到了我所需要的,但我希望使用C#驱动程序实现这一点的方法不那么神奇

我的工作查找/更新如下所示:

{   
    "subdoc": [
        {
            "key": 1,
            "value": "abc",
            "isActive": true
        },
        {
            "key":5,
            "value": "ade",
            "isActive":true
        }
    ]
}
{   
    "subdoc": [
        {
            "key": 1,
            "value": "abc",
            "isActive": true
        },
        {
            "key":5,
            "value": "ade",
            "isActive": false,
            "deletedAt": Timestamp(1425911075,1)
        }
    ]
}
// find
{
    "subdoc.key":"2",
    "subdoc.value":"ade"
}
// update
{   
    "$currentDate": {
        "subdoc.$.deleteAt": {
            "$type": "timestamp"
        }
    }
}
更新:我应该澄清,此更新的时间戳字段用于负载平衡环境(多个web服务器、多个工作进程和一个mongo群集)中许多有时连接的移动客户端的同步具有高事务量,这使得此时间戳具有单点真实性至关重要,在应用程序上下文中是逻辑顺序的,并且尽可能高的精度(几分之一秒)。否则,记录可能会在同步过程中丢失

目前,我正在使用上述方法确保mongo数据库实例生成时间戳值。我对这种方法非常满意。

您可以使用c#驱动程序将mongo实体包装到c#对象中。然后在代码中,您可以使用linq查询数据库并根据需要更新对象。然后只需保存em到DB以保留您的更改

下面是一小段代码,用于查询
test
DB中的
Parent
集合。 C#驱动程序提供as
AsQueryable
扩展,允许我们直接在Linq中编写查询。然后,驱动程序将自动生成所需的查询并对集合执行它

下面的示例查找
子文档
列表中
字段值为5的所有子文档

如果找到任何,它将更新deletedAt日期,然后将其保存回数据库

var client = new MongoClient();
var database = client.GetServer().GetDatabase("test");
var parentCollection = database.GetCollection<Parent>("Parent");

var parent = parentCollection.AsQueryable().FirstOrDefault(p => p.subdoc.Any(f => f.key == 5));

if (parent != null)
{
    var fooList = parent.subdoc.Where(f => f.key == 5);
    foreach (var foo in fooList)
    {
        foo.deletedAt = DateTime.UtcNow;
    }
}

parentCollection.Save(parent);

请参阅最新更新。位置运算符和$currentDate运算符的组合符合我的目的。

Hmm。我从未注意到保存方法。这可能会很方便。在这种情况下,我也在寻找服务器端更改排序解决方案。服务器填写的BsonTimestamp数据类型是否也能实现同样的效果?一个wa要做到这一点,需要在DAL层中构建一个预保存操作,该操作将在实体保存到DB之前执行任何操作。我们使用这种方法来更新实体的最新更新日期等。这是自动发生的,我们不必自己在代码中更新字段。