MongoDB:如何为单个文档投影所有字段类型?
我需要检查给定集合中每个文档中的每个字段类型MongoDB:如何为单个文档投影所有字段类型?,mongodb,types,mongodb-query,aggregation-framework,Mongodb,Types,Mongodb Query,Aggregation Framework,我需要检查给定集合中每个文档中的每个字段类型 虽然我可以为每个字段编写单独的$type命令,并分别为每个文档进行匹配,但我想知道是否有一种更优雅、更高效的方法可以直接投影所有字段类型。您需要枚举所有字段并单独处理每个字段。为了枚举的目的,您可以结合使用$objectToArray和$unwind,然后使用$push和$arrayToObject将所有内容重新分组在一起: db.collection.aggregate([ // Convert the root document into
虽然我可以为每个字段编写单独的
$type
命令,并分别为每个文档进行匹配,但我想知道是否有一种更优雅、更高效的方法可以直接投影所有字段类型。您需要枚举所有字段并单独处理每个字段。为了枚举的目的,您可以结合使用$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
将其放入字段数组中。尝试以下操作:
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"
}
}
结果:
/* 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"
}
}
注意:此给定查询仅适用于文档中的顶级字段,它不会从以下字段中获取对象的类型:
:
"Object" : {
"inOneObject" : true
}
您是否尝试过使用mongo Compass产品
我相信对于这个要求来说这很容易……这可能正适合我的需要。谢谢你们两位。@Ben:嘿,你们能接受这个吗?这样你们的问题就会被标记为完整的,并有一个有效的答案。。