MongoDB分组和项目自定义字段

时间:2018-07-16 10:42:29

标签: mongodb mongodb-query aggregation-framework mongodb-.net-driver

我被MongoDB分组和项目自定义字段所困扰。我有以下收藏:

{ 
    "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"
}

是否有可能基于“类型”字段来投影字段,例如将“类型”值与字段名称进行连接,如下所示:

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

1 个答案:

答案 0 :(得分:0)

要重命名对象的键,必须使用$objectToArray$arrayToObject运算符。第一个可以将$$ROOT对象转换为键和值的数组。然后,您可以应用$map来修改密钥(使用$concat)和$filter来排除Type密钥。然后,您可以使用$arrayToObject将该数组转换回对象,并使用$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运算符