我被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"
}
答案 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