MongoDB 分组和项目自定义字段

MongoDB Grouping and Project Custom Fields

我受困于 MongoDB 分组和项目自定义字段。我有以下 collection:

{ 
    "DescId" : "1", 
    "Desc" : "Testing", 
    "ParentId" : "null", 
    "Order" : 1.0, 
    "Type" : "A", 
    "Parent" : null
}

{ 
    "DescId" : "1.1", 
    "Desc" : "Testing Child 1", 
    "ParentId" : "1", 
    "Order" : 1.0, 
    "Type" : "B", 
    "Parent" : "Testing"
}

{ 
    "DescId" : "1.2", 
    "Desc" : "Testing Child 2", 
    "ParentId" : "1", 
    "Order" : 2.0, 
    "Type" : "B", 
    "Parent" : "Testing"
}

我已经根据类型、DescId、Desc 字段和预计的 DescId 和 Desc 完成了以下分组

db.getCollection("GenericData").aggregate(
[
    { 
        "$group" : {
            "_id" : {
                "Type" : "$Type", 
                "DescId" : "$DescId", 
                "DescName" : "$Desc"
            }
        }
    }, 
    { 
        "$project" : {
            "_id" : 0.0, 
            "Id" : "$_id.DescId", 
            "Name" : "$_id.DescName", 
            "Type" : "$_id.Type"
        }
    }
], 
{ 
    "allowDiskUse" : false
}

);

这是我得到的输出:

{ 
    "Id" : "1.2", 
    "Name" : "Testing Child 2", 
    "Type" : "B"
}
{ 
    "Id" : "1.1", 
    "Name" : "Testing Child 1", 
    "Type" : "B"
}
{ 
    "Id" : "1", 
    "Name" : "Testing", 
    "Type" : "A"
}

是否可以基于 Type 字段投影字段,例如将 Type 值与字段名称连接起来,如下所示:

{
    "A" + "Id" : "1",
    "A" + "Name" : "Testing"
},
{
   "B" + "Id" : "1.1",
   "B" + "Name" : "Testing Child 1"
}
{
   "B" + "Id" : "1.2",
   "B" + "Name" : "Testing Child 2"
}

要重命名对象的键,您必须使用 $objectToArray and $arrayToObject operators. First one can convert your $$ROOT object into an array of keys and values. Then you can apply $map to modify keys (using $concat) and $filter to exclude Type key. Then you can convert that array back to an object using $arrayToObject and promote that object to a root level using $replaceRoot。因此,您可以将以下阶段添加到聚合管道中:

db.GenericData.aggregate([
    {
        $replaceRoot: {
            newRoot: {
                $arrayToObject: {
                    $map: {
                        input: { 
                            $filter: { 
                                input: { $objectToArray: "$$ROOT" }, 
                                as: "kv", 
                                cond: { $in: [ "$$kv.k", [ "Id", "Name" ] ] } 
                            }
                        },
                        as: "kv",
                        in: {
                            k: { $concat: [ "$Type", "$$kv.k" ] },
                            v: "$$kv.v"
                        }
                    }
                }
            }
        }
    }
])

输出:

{ "BId" : "1.2", "BName" : "Testing Child 2" }
{ "BId" : "1.1", "BName" : "Testing Child 1" }
{ "AId" : "1", "AName" : "Testing" }

编辑: 如果您想明确指定应该投影哪些属性,您可以在 $filter

中使用 $in 运算符