我正在尝试获取一组结果,其中玩家名称以字符串格式分隔,但我似乎无法使其工作。我可以让player数组连接每个子文档的名字和姓氏,但是将它们连接成一个字符串是失败的。
这是我目前的结果:
{ "event" : "Junior Girls 16s", "field" : "Main", "players" : [ { "name" : "Mary Mack" }, { "name" : "Mary Minor" } ], "net" : 4, "team" : 2 }
{ "event" : "Junior Girls 16s", "field" : "Main", "players" : [ { "name" : "Jane Doe" }, { "name" : "Julie Doe" } ], "net" : 3, "team" : 3 }
{ "event" : "Junior Girls 16s", "field" : "Main", "players" : [ { "name" : "Melanie Maygonuts" }, { "name" : "Mackenzie Mightbecray" } ], "net" : 3, "team" : 4 }
{ "event" : "Junior Girls 16s", "field" : "Main", "players" : [ { "name" : "Isabella Iamluny" }, { "name" : "Alexis Alreadythere" } ], "net" : 3, "team" : 5 }
这就是我想要的结果:
{"event" : "Junior Girls 16s", "field" : "Main", "team" : "Mary Mack / Mary Minor", "net" : 4, "team" : 2 }
{ "event" : "Junior Girls 16s", "field" : "Main", "team" : "Jane Doe / Julie Doe", "net" : 3, "team" : 3 }
{ "event" : "Junior Girls 16s", "field" : "Main", "team" : "Melanie Maygonuts / Mackenzie Mightbecray", "net" : 3, "team" : 4 }
{ "event" : "Junior Girls 16s", "field" : "Main", "team" : "Isabella Iamluny / Alexis Alreadythere", "net" : 3, "team" : 5 }
第一组结果的代码:
db.registrations.aggregate([
{$match: {event: "Junior Girls 16s"}},
{$project: {event: "$event", field: "$field", net: "$net", team: "$team",
"players": {
"$map": {
"input": "$players",
"as": "u",
"in": {
"name": { "$concat" : [ "$$u.first", " ", "$$u.last" ] }
}
}
} }}
])
这是我上次尝试的代码,它给出了一个错误无效的运算符reduce:
db.registrations.aggregate([
{$match: {event: "Junior Girls 16s"}},
{$project: {event: "$event", field: "$field", net: "$net", team: "$team",
"players": {
"$map": {
"input": "$players",
"as": "u",
"in": {
"name": { "$concat" : [ "$$u.first", " ", "$$u.last" ] }
}
}
}
}},
{$project: {event: "$event", field: "$field", net: "$net", team: "$team",
"players": {
$reduce: {
input: "$players",
initialValue: "",
in: { $concat: ['$$name', ' / ', '$$this'] }
}
}
}}
])
我错过了什么?我觉得我很接近,但却无法操纵我想要的数据。
答案 0 :(得分:2)
这实际上不应该通过聚合框架来完成,但无论如何我们都会展示这个例子。
如前所述,您的具体错误是因为您没有支持$reduce
的MongoDB,这意味着MongoDB 3.4或更高版本。但是,当您进行升级时,您可以执行以下声明:
db.registrations.aggregate([
{ "$addFields": {
"players": {
"$reduce": {
"input": { "$filter": {
"input": {
"$reduce": {
"input": { "$zip": {
"inputs": [
{ "$map": {
"input": "$players",
"as": "u",
"in": { "$concat": [ "$$u.first", " ", "$$u.last" ] }
}},
{ "$map": {
"input": {
"$range": [ 0, { "$subtract": [ { "$size": "$players" }, 1 ] } ]
},
"as": "el",
"in": " / "
}}
],
"useLongestLength": true
}},
"initialValue": [],
"in": { "$concatArrays": [ "$$value", "$$this" ] }
}
},
"as": "el",
"cond": { "$ne": [ "$$el", null ] }
}},
"initialValue": "",
"in": { "$concat": [ "$$value", "$$this" ] }
}
}
}}
])
这将产生所需的输出:
{
"_id" : ObjectId("592cfbc3820a42bc1e825de7"),
"event" : "Junior Girls 16s",
"field" : "Main",
"players" : "Mary Mack / Mary Minor",
"net" : 4,
"team" : 2
}
{
"_id" : ObjectId("592cfbc3820a42bc1e825de8"),
"event" : "Junior Girls 16s",
"field" : "Main",
"players" : "Jane Doe / Julie Doe",
"net" : 3,
"team" : 3
}
{
"_id" : ObjectId("592cfbc3820a42bc1e825de9"),
"event" : "Junior Girls 16s",
"field" : "Main",
"players" : "Melanie Maygonuts / Mackenzie Mightbecray",
"net" : 3,
"team" : 4
}
{
"_id" : ObjectId("592cfbc3820a42bc1e825dea"),
"event" : "Junior Girls 16s",
"field" : "Main",
"players" : "Isabella Iamluny / Alexis Alreadythere",
"net" : 3,
"team" : 5
}
咀嚼它是不是很满口呢?这就是为什么你不这样做,而只是在客户端代码中读取数据的这种转换。
作为shell的一个简单的JavaScript示例:
db.registrations.find().forEach( doc => {
doc.players = doc.players
.map( p => `${p.first} ${p.last}` )
.join(" / ");
printjson(doc)
})
输出完全相同的东西。看看现在有多清洁。
请注意,这个使用的源数据如原始数组内容所具有的问题中所述" first"和"最后"数组中名称的字段:
{ "_id" : ObjectId("592cfbc3820a42bc1e825de7"), "event" : "Junior Girls 16s", "field" : "Main", "players" : [ { "first" : "Mary", "last" : "Mack" }, { "first" : "Mary", "last" : "Minor" } ], "net" : 4, "team" : 2 }
{ "_id" : ObjectId("592cfbc3820a42bc1e825de8"), "event" : "Junior Girls 16s", "field" : "Main", "players" : [ { "first" : "Jane", "last" : "Doe" }, { "first" : "Julie", "last" : "Doe" } ], "net" : 3, "team" : 3 }
{ "_id" : ObjectId("592cfbc3820a42bc1e825de9"), "event" : "Junior Girls 16s", "field" : "Main", "players" : [ { "first" : "Melanie", "last" : "Maygonuts" }, { "first" : "Mackenzie", "last" : "Mightbecray" } ], "net" : 3, "team" : 4 }
{ "_id" : ObjectId("592cfbc3820a42bc1e825dea"), "event" : "Junior Girls 16s", "field" : "Main", "players" : [ { "first" : "Isabella", "last" : "Iamluny" }, { "first" : "Alexis", "last" : "Alreadythere" } ], "net" : 3, "team" : 5 }