问题
I am using this data:
{
"world": "Comic",
"characters": [
{
"character": "megaman",
"type":"hero",
"code":"123"
},
{
"character": "dr willow",
"type":"villain",
"code":"1234"
},
{
"character": "spiderman",
"type":"hero",
"code":"12345"
},
{
"character": "venom",
"type":"villain",
"code":"123456"
}
]
}
With this code:
db.collection.aggregate([
{$addFields:{
array_hero:{
$filter:{
input: "$characters",
cond: {$eq:["$$this.type","hero"]}
}
},
array_villain:{
$filter:{
input: "$characters",
cond: {$eq:["$$this.type","villain"]}
}
},
}}
])
the output is:
{
"array_hero": [
{
"character": "megaman",
"type": "hero",
"code": "123"
},
{
"character": "spiderman",
"type": "hero",
"code": "12345"
}
],
"array_villain": [
{
"character": "dr willow",
"type": "villain",
"code": "1234"
},
{
"character": "venom",
"type": "villain",
"code": "123456"
}
]
}
I want to have this output, where the arrays are only built with the characters.code
like this:
{
"array_hero": [
"123","12345"
],
"array_villain": [
"1234","123456"
]
}
how can I do it?
回答1:
Your aggregation query is almost there. Just added a $map stage to pick the required fields/attributes.
db.collection.aggregate([
{
$addFields: {
array_hero: {
$filter: {
input: "$characters",
cond: {
$eq: [
"$$this.type",
"hero"
]
}
}
},
array_villain: {
$filter: {
input: "$characters",
cond: {
$eq: [
"$$this.type",
"villain"
]
}
}
},
},
},
{
$project: {
array_hero: {
$map: {
input: "$array_hero",
as: "hero",
in: "$$hero.code"
}
},
array_villain: {
$map: {
input: "$array_villain",
as: "villain",
in: "$$villain.code"
}
},
}
}
])
Play link
回答2:
Say we have saved following document into a collection named collection
.
db.collection.save(
{
"world": "Comic",
"characters": [
{
"character": "megaman",
"type":"hero",
"code":"123"
},
{
"character": "dr willow",
"type":"villain",
"code":"1234"
},
{
"character": "spiderman",
"type":"hero",
"code":"12345"
},
{
"character": "venom",
"type":"villain",
"code":"123456"
}
]
}
)
Then the following command would return codes grouped by different types of characters that the world
field is Comic
in this collection:
db.collection.aggregate([
{
$match: {
world: "Comic"
},
},
{
$unwind: "$characters"
},
{
$group: {
_id: "$characters.type",
codes: {$addToSet: "$characters.code"}
}
},
{
$project: {
_id: 0,
type: "$_id",
codes: 1
}
}
])
The result running above command in mongo shell is as following:
{ "codes" : [ "12345", "123" ], "type" : "hero" }
{ "codes" : [ "123456", "1234" ], "type" : "villain" }
来源:https://stackoverflow.com/questions/62938971/how-to-output-map-an-array-with-only-the-required-fields-after-a-filter-in-mong