我需要检查给定集合中每个文档中的每个字段类型。
虽然我可以为每个字段编写单独的$type
命令并分别为每个文档进行匹配,但我想知道是否有一种更优雅,更有效的方式来投影所有字段类型。
答案 0 :(得分:2)
尝试一下:
db.collection.aggregate([{
$addFields: {
types: {
$arrayToObject: {
$map:
{
input: { $objectToArray: "$$ROOT" },
as: "each",
in: { k: '$$each.k', v: { $type: '$$each.v' } }
}
}}
}
}])
收集数据:
/* 1 */
{
"_id" : ObjectId("5e065992400289966eefb9a8"),
"username" : "myName",
"blog" : "myBlog",
"details" : "myBlogDetails",
"Object" : {
"inOneObject" : true
}
}
/* 2 */
{
"_id" : ObjectId("5e0659ae400289966eefbc3a"),
"username" : "othersName",
"blog" : "not a blog",
"details" : "useless"
}
结果:
/* 1 */
{
"_id" : ObjectId("5e065992400289966eefb9a8"),
"username" : "myName",
"blog" : "myBlog",
"details" : "myBlogDetails",
"Object" : {
"inObject" : true
},
"types" : {
"_id" : "objectId",
"username" : "string",
"blog" : "string",
"details" : "string",
"Object" : "object"
}
}
/* 2 */
{
"_id" : ObjectId("5e0659ae400289966eefbc3a"),
"username" : "othersName",
"blog" : "not a blog",
"details" : "useless",
"types" : {
"_id" : "objectId",
"username" : "string",
"blog" : "string",
"details" : "string"
}
}
注意::该给定查询仅适用于文档中的顶级字段,它不会使您从字段::
下输入inObject
类型
"Object" : {
"inOneObject" : true
}
答案 1 :(得分:1)
您需要枚举所有字段并分别处理每个字段。您可以使用$objectToArray
和$unwind
的组合来进行枚举,然后使用$push
和$arrayToObject
来将所有内容重新组合在一起:
db.collection.aggregate([
// Convert the root document into an array.
{$project: {
fields: {
$objectToArray: "$$ROOT"
}
}},
// Turn each array element into a separate document representing a field-value pair of the root document.
{$unwind: "$fields"},
// Apply the $type projection to the value portion of the field-value pair.
{$project: {
fields: {
k: "$fields.k",
v: {$type: "$fields.v"}
}
}},
// Grab the first instance of each unique field name.
{$group: {
_id: "$fields.k",
fields: {$first: "$fields"}
}},
// Take the unique field instances and recollect them all into an array.
{$group: {
_id: null,
fields: {$push: "$fields"}
}},
// Convert our array back into an object.
{$project: {
fields: {$arrayToObject: "$fields"}
}},
// Replace the root document with our nested "fields" sub-document.
{$replaceRoot: {
newRoot: "$fields"
}}
])
一个小警告:如果该字段可能包含多种类型,例如“ string”和“ null”,那么此解决方案将不会解决这种情况。要解决该问题,您需要修改$group
阶段以利用$addToSet
运算符为每个键$type
将其唯一$push
实例收集到每个键之前, fields
数组。
答案 2 :(得分:-1)
您是否尝试过使用mongo Compass产品?
对于这个要求,我相信这很容易.....