在 MongoDb 中,如何为数组 属性 中的对象设置值?
In MongoDb, how can you set a value on an object in a array property?
我的目标是在文档数组中的特定对象上放置一个 "deleted at" 时间戳。
如果文件看起来像这样:
{
"subdoc": [
{
"key": 1,
"value": "abc",
"isActive": true
},
{
"key":5,
"value": "ade",
"isActive":true
}
]
}
我希望能够说 "look for the document that has subdoc.key == 5 and subdoc.value == "ade";将 subdoc.isActive 设置为 false 并设置 subdoc.deleteAt = 当前数据库时间戳。生成的文档如下所示:
{
"subdoc": [
{
"key": 1,
"value": "abc",
"isActive": true
},
{
"key":5,
"value": "ade",
"isActive": false,
"deletedAt": Timestamp(1425911075,1)
}
]
}
这可行吗?
更新:在进一步查看 mongo 文档后,使用“$(更新)”运算符似乎确实可行。这让我得到了我需要的东西,但我希望使用 C# 驱动程序使用一种不那么神奇的字符串方式来做到这一点?
我的工作 find/update 看起来像这样:
// find
{
"subdoc.key":"2",
"subdoc.value":"ade"
}
// update
{
"$currentDate": {
"subdoc.$.deleteAt": {
"$type": "timestamp"
}
}
}
更新:我应该澄清一下,这个更新的时间戳字段用于负载平衡环境(多个 Web 服务器、多个工作进程和 mongo 集群)中许多有时连接的移动客户端的同步) 具有高交易量,这使得此时间戳具有单点真实性、在应用程序上下文中逻辑顺序且尽可能高精度(几分之一秒)这一点至关重要。否则,记录可能会在同步中丢失。
目前,我正在使用上述方法来确保 mongo 数据库实例生成时间戳值。我对这种方法非常满意。
您可以使用 c# 驱动程序将 mongo 实体包装在 c# 对象中。然后在您的代码中,您可以使用 linq 查询数据库并根据需要更新您的对象。然后将它们保存到数据库以保留您的更改。
下面是一小段代码,用于查询 test
数据库中的 Parent
集合。
C# 驱动程序提供 AsQueryable
扩展,允许我们直接在 Linq 中编写查询。然后驱动程序将自动构建所需的查询并针对集合执行它。
下面的示例查找 subdoc
列表中 key
字段值为 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);
下面是用于映射到 Mongo 文档的两个 c# 实体。我们可以使用 mongo c# 驱动程序的 [BsonIgnoreIfNull]
属性来仅序列化包含值的 deletedAt
字段。我们还在代码中使用可为空的 DateTime
对象,以允许在需要时存储空值。
public class Foo
{
[BsonId]
public ObjectId Id { get; set; }
public int key { get; set; }
public string value { get; set; }
public bool isActive { get; set; }
[BsonIgnoreIfNull]
public DateTime? deletedAt { get; set; }
}
public class Parent
{
[BsonId]
public ObjectId Id { get; set; }
public List<Foo> subdoc { get; set; }
}
查看最新更新。位置运算符和 $currentDate 运算符的组合正在满足我的目的。
我的目标是在文档数组中的特定对象上放置一个 "deleted at" 时间戳。
如果文件看起来像这样:
{
"subdoc": [
{
"key": 1,
"value": "abc",
"isActive": true
},
{
"key":5,
"value": "ade",
"isActive":true
}
]
}
我希望能够说 "look for the document that has subdoc.key == 5 and subdoc.value == "ade";将 subdoc.isActive 设置为 false 并设置 subdoc.deleteAt = 当前数据库时间戳。生成的文档如下所示:
{
"subdoc": [
{
"key": 1,
"value": "abc",
"isActive": true
},
{
"key":5,
"value": "ade",
"isActive": false,
"deletedAt": Timestamp(1425911075,1)
}
]
}
这可行吗?
更新:在进一步查看 mongo 文档后,使用“$(更新)”运算符似乎确实可行。这让我得到了我需要的东西,但我希望使用 C# 驱动程序使用一种不那么神奇的字符串方式来做到这一点?
我的工作 find/update 看起来像这样:
// find
{
"subdoc.key":"2",
"subdoc.value":"ade"
}
// update
{
"$currentDate": {
"subdoc.$.deleteAt": {
"$type": "timestamp"
}
}
}
更新:我应该澄清一下,这个更新的时间戳字段用于负载平衡环境(多个 Web 服务器、多个工作进程和 mongo 集群)中许多有时连接的移动客户端的同步) 具有高交易量,这使得此时间戳具有单点真实性、在应用程序上下文中逻辑顺序且尽可能高精度(几分之一秒)这一点至关重要。否则,记录可能会在同步中丢失。
目前,我正在使用上述方法来确保 mongo 数据库实例生成时间戳值。我对这种方法非常满意。
您可以使用 c# 驱动程序将 mongo 实体包装在 c# 对象中。然后在您的代码中,您可以使用 linq 查询数据库并根据需要更新您的对象。然后将它们保存到数据库以保留您的更改。
下面是一小段代码,用于查询 test
数据库中的 Parent
集合。
C# 驱动程序提供 AsQueryable
扩展,允许我们直接在 Linq 中编写查询。然后驱动程序将自动构建所需的查询并针对集合执行它。
下面的示例查找 subdoc
列表中 key
字段值为 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);
下面是用于映射到 Mongo 文档的两个 c# 实体。我们可以使用 mongo c# 驱动程序的 [BsonIgnoreIfNull]
属性来仅序列化包含值的 deletedAt
字段。我们还在代码中使用可为空的 DateTime
对象,以允许在需要时存储空值。
public class Foo
{
[BsonId]
public ObjectId Id { get; set; }
public int key { get; set; }
public string value { get; set; }
public bool isActive { get; set; }
[BsonIgnoreIfNull]
public DateTime? deletedAt { get; set; }
}
public class Parent
{
[BsonId]
public ObjectId Id { get; set; }
public List<Foo> subdoc { get; set; }
}
查看最新更新。位置运算符和 $currentDate 运算符的组合正在满足我的目的。