MongoDb中动态字段的查询
我试图在MongoDb中查询一些具有已知文档结构但字段未知的数据。这是我的测试集合中的三个文档。在本例中,“Data1”和“Data2”字段是已知值,但子文档中的字段是未知的(例如NumberOfVehicles、LocationOfIncident和TestReason) 我想在所有文档中查询特定的数据部分(“Data1”),并得到如下结果:MongoDb中动态字段的查询,mongodb,mongodb-query,Mongodb,Mongodb Query,我试图在MongoDb中查询一些具有已知文档结构但字段未知的数据。这是我的测试集合中的三个文档。在本例中,“Data1”和“Data2”字段是已知值,但子文档中的字段是未知的(例如NumberOfVehicles、LocationOfIncident和TestReason) 我想在所有文档中查询特定的数据部分(“Data1”),并得到如下结果: { "_id" : "5a32cf74cbf20b446c70f969", "CreatedDate" : "2017-12-14 19:22:
{
"_id" : "5a32cf74cbf20b446c70f969",
"CreatedDate" : "2017-12-14 19:22:05.233Z",
"NumberOfVehicles" : "4",
"LocationOfIncident" : "Bangor"
},
{
"_id" : "5a3abff0ccf20b17642214b7",
"CreatedDate" : "2017-12-20T19:53:56.318Z",
"NumberOfVehicles" : "5"
}
我很接近,但似乎无法摆脱阵列。以下是我目前掌握的情况:
db.runCommand({
aggregate: "test",
pipeline: [
{ $group: { _id: "$Data.Data1" } },
{ $unwind: "$_id" }
]
}).result
其中:
[
{
"_id" : {
"NumberOfVehicles" : "4",
"LocationOfIncident" : "Bangor"
}
},
{
"_id" : {
"NumberOfVehicles" : "5"
}
}
]
关于如何将它更多地转换成表格格式(如上面我想要的格式)有什么建议吗?此数据正在第三方报告产品中使用,需要更像表格的结构。您可以在3.6版本中使用下面的聚合查询
$match
阶段筛选存在Data1
的文档
$unwind
以展平数据1中的数据
$mergeObjects
将其他文档字段与$let
表达式合并,以删除嵌入的文档结构和项目嵌入的数据1字段
$replaceRoot
将数据提升到顶层
$project
,排除以删除数据
字段
db.testcol.aggregate([
{"$match":{"Data.Data1":{$exists:true}}},
{"$unwind":"$Data.Data1"},
{"$replaceRoot":{
"newRoot":{
"$mergeObjects":[
"$$ROOT",
{
"$let":{
"vars":{"data1":"$Data.Data1"},
"in":"$$data1"
}
}
]
}
}},
{"$project":{"Data":0}},
])
您可以在3.6版本中使用以下聚合查询
$match
阶段筛选存在Data1
的文档
$unwind
以展平数据1中的数据
$mergeObjects
将其他文档字段与$let
表达式合并,以删除嵌入的文档结构和项目嵌入的数据1字段
$replaceRoot
将数据提升到顶层
$project
,排除以删除数据
字段
db.testcol.aggregate([
{"$match":{"Data.Data1":{$exists:true}}},
{"$unwind":"$Data.Data1"},
{"$replaceRoot":{
"newRoot":{
"$mergeObjects":[
"$$ROOT",
{
"$let":{
"vars":{"data1":"$Data.Data1"},
"in":"$$data1"
}
}
]
}
}},
{"$project":{"Data":0}},
])
您可以从筛选集合开始,只留下包含
数据的文档。Data1
。然后,您需要将其展开,以使用单个项Data1
将元素数组转换为多个文档。然后,您必须将两个字段\u id
和CreatedDate
移动到Data1
的两个更深层次,以便能够使用它们获得所需的准确形状
db.collection.aggregate([
{
$match: {
"Data.Data1": { $exists : true }
}
},
{ $unwind: "$Data.Data1" },
{
$addFields: {
"Data.Data1.CreatedDate": "$CreatedDate",
"Data.Data1._id": "$_id"
}
},
{
$replaceRoot: {
newRoot: "$Data.Data1"
}
}
])
您可以从筛选集合开始,只留下包含
数据的文档。Data1
。然后,您需要将其展开,以使用单个项Data1
将元素数组转换为多个文档。然后,您必须将两个字段\u id
和CreatedDate
移动到Data1
的两个更深层次,以便能够使用它们获得所需的准确形状
db.collection.aggregate([
{
$match: {
"Data.Data1": { $exists : true }
}
},
{ $unwind: "$Data.Data1" },
{
$addFields: {
"Data.Data1.CreatedDate": "$CreatedDate",
"Data.Data1._id": "$_id"
}
},
{
$replaceRoot: {
newRoot: "$Data.Data1"
}
}
])
CreatedDate和_id将在您的解决方案中丢失。是的,您是正确的。我没有注意到问题的那一部分。已更新now.CreatedDate和_id将在您的解决方案中丢失。是的,您是正确的。我没有注意到问题的那一部分。现在更新。看起来
$addFields
和$replaceRoot
在比我使用的版本(v3.2)更高的版本(v3.4)中受支持。我将在本地升级并尝试您的解决方案。如果我无法升级我们的环境(至少在不久的将来),是否可以使用其他方法在v3.2中实现同样的升级?您仍然可以在3.2中使用$match和$unwind,然后在客户端转换数据。这应该不会影响性能。我在本地升级到v3.4,您的查询成功了!非常感谢!看起来$addFields
和$replaceRoot
在比我使用的版本(v3.2)更高的版本(v3.4)中受支持。我将在本地升级并尝试您的解决方案。如果我无法升级我们的环境(至少在不久的将来),是否可以使用其他方法在v3.2中实现同样的升级?您仍然可以在3.2中使用$match和$unwind,然后在客户端转换数据。这应该不会影响性能。我在本地升级到v3.4,您的查询成功了!非常感谢!