假设我有一个像这样的简单集合:
[
{
Brands: [
{ BID: 1, Prods: [ { PID: 10 }, { PID: 11 } ] },
{ BID: 2, Prods: [ { PID: 20 }, { PID: 21 } ] }
]
},
{
Brands: [
{ BID: 3, Prods: [ { PID: 30 }, { PID: 31 }, { PID: 32 } ] }
]
}
]
我想从
PID
中提取所有独特的Prods
,所以结果是:
[10,11,20,21,30,31,32]
这样做我可以接近这个:
db.collection.aggregate([
{
$project: {
"AllProds": {
"$map": {
"input": "$Brands.Prods",
"as": "elem",
"in": "$$elem.PID"
}
}
}
}
])
但结果不是一个简单的数组,它是一个内部有
PID
的对象数组:
[
{
"AllProds": [
[ 10, 11 ],
[ 20, 21 ]
],
"_id": ObjectId("5a934e000102030405000000")
},
{
"AllProds": [
[ 30, 31, 32 ]
],
"_id": ObjectId("5a934e000102030405000001")
}
]
您在这里并不完全需要
$map
。只需展开外部数组,然后
内部数组并将它们分组在一起
db.getCollection('SampleCollection').aggregate([
{
$unwind:"$Brands"
},
{
$unwind:"$Brands.Prods"
},
{
$group:
{
_id:null,
PIDs: {$push:"$Brands.Prods.PID"}//use $addToSet instead of $push if you do not wish to allow duplicates
}
}
])
$group
为 null 并创建 Brands
数组$project
,$reduce
迭代$Brands
数组的循环,$reduce
使用$concatArrays
db.collection.aggregate([
{
$group: {
_id: null,
Brands: { $push: "$Brands.Prods.PID" }
}
},
{
$project: {
_id: 0,
Brands: {
$reduce: {
input: "$Brands",
initialValue: [],
in: {
$concatArrays: [
"$$value",
{
$reduce: {
input: "$$this",
initialValue: [],
in: { $concatArrays: ["$$value", "$$this"] }
}
}
]
}
}
}
}
}
])
您只需再执行 2 个 $unwind 即可展平数组。然后使用 $group 和 $addToSet 来获取结果。
db.collection.aggregate([
{
$project: {
"AllProds": {
"$map": {
"input": "$Brands.Prods",
"as": "elem",
"in": "$$elem.PID"
}
}
}
},
{
"$unwind": "$AllProds"
},
{
"$unwind": "$AllProds"
},
{
"$group": {
"_id": null,
"uniquePids": {
"$addToSet": "$AllProds"
}
}
}
])
这里是mongo游乐场供您参考。