我有一个包含字典的对象集合,并且只想提取键而不是字典中的值(它们比键大得多,与下面的示例不同)我正在使用 MongoDb.Driver 2.10 C#。
假设我有以下收藏:
{ "_id" : "1", "Contents":{"item11":{}, "item12":{} } },
{ "_id" : "2", "Contents":{"item21":{} } },
{ "_id" : "3", "Contents":{"item31":{}, "item32":{}, "item33":{} } }
我想要一个返回以下内容的查询:
{ "1": ["item11", "item12"],
"2": ["item21"],
"3": ["item31", "item32", "item33"] }
$set
- 通过将 Contents
转换为具有 Contents
和 k
字段的文档来检索 v
数组中的键,并提取 k
值。
$group
- 将所有文档分组并将文档添加到 data
数组中。
$replaceWith
- 将输入文档替换为 data
数组中的键值对与 $arrayToObject
。
db.collection.aggregate([
{
$set: {
keys: {
$map: {
input: {
$objectToArray: "$Contents"
},
in: "$$this.k"
}
}
}
},
{
$group: {
_id: null,
data: {
$push: {
k: "$_id",
v: "$keys"
}
}
}
},
{
$replaceRoot: {
newRoot: {
$arrayToObject: "$data"
}
}
}
])
我认为在 MongoDB C# 语法中,编写 Fluent 语法会很棘手,但您可以通过将查询从 MongoDB Compass 导出为语言来使用
BsonDocument
进行查询。
var pipeline = new BsonDocument[]
{
new BsonDocument("$set",
new BsonDocument("keys",
new BsonDocument("$map",
new BsonDocument
{
{ "input", new BsonDocument("$objectToArray", "$Contents") },
{ "in", "$$this.k" }
}))),
new BsonDocument("$group",
new BsonDocument
{
{ "_id", BsonNull.Value },
{ "data",
new BsonDocument("$push",
new BsonDocument
{
{ "k", "$_id" },
{ "v", "$keys" }
}) }
}),
new BsonDocument("$replaceRoot",
new BsonDocument("newRoot",
new BsonDocument("$arrayToObject", "$data")))
};
var result = collection.Aggregate<BsonDocument>(pipeline)
.ToList();