如何解决Mongodb 循环遍历每个不同的值并使用聚合方面选择标签
我有这样的收藏:
{
"labels": [{
"description": "Dog"
},{
"description": "Red"
},{
"description": "XXX"
}]
}
{
"labels": [{
"description": "Cat"
},{
"description": "XXX"
},{
"description": "Yellow"
}]
}
{
"labels": [{
"description": "Dog"
},{
"description": "Yellow"
}]
}
{
"labels": [{
"description": "Bird"
},{
"description": "XXX"
}]
}
例如,我只想从所有元素和输出文档中过滤“红色”和“黄色”颜色,如下所示:
// because "Dog" appears 2 times so total = 2
{
description: "Dog",total: 2,colors: [
{ "_id": "Red",total: 2 },{ "_id": "Yellow",total: 1 }
]
}
{
description: "Cat",total: 1,colors: [
{ "_id": "Yellow",total: 1 }
]
}
{
description: "Bird",colors: []
}
{
description: "Red",colors: [
{ _id: "Yellow",total: 1 }
]
}
{
description: "XXX",total: 4,total: 1 }
]
}
我可以通过使用 collection.distinct('labels.description')
然后遍历每个元素 + 像这样创建一个单独的 collection.count({ 'labels.description': 'Dog' })
来做到这一点:
for (...)
db.collection.aggregate([
{
"$match": {
"labels.description": valueFromLoop // (e.g. Dog)
}
},{ $unwind : "$labels" },{
"$group": {
"_id": "$labels.description","count": { "$sum": 1 }
}
},{
"$match": {
"$or": [
{ "_id": "Red" },{ "_id": "Yellow" }
]
}
},{
"$sort": {
"count": -1
}
}
])
我想在单个聚合或 mapReduce 中执行此操作,以便我可以使用 $out 轻松将其输出到新集合,而不是单独使用批量操作,但是我不知道是否可行。
解决方法
试试这个:
let filter = ["Red","Yellow"];
db.testcollection.aggregate([
{
$addFields: { bkp: "$labels" }
},{ $unwind: "$labels" },{
$addFields: {
bkp: {
$filter: {
input: "$bkp",as: "item",cond: {
$and: [
{ $ne: ["$$item.description","$labels.description"] },{ $in: ["$$item.description",filter] }
]
}
}
}
}
},{
$unwind: {
path: "$bkp",preserveNullAndEmptyArrays: true
}
},{
$group: {
_id: {
key1: "$labels.description",key2: { $ifNull: ["$bkp.description",false] }
},total: { $sum: 1 }
}
},{
$group: {
_id: "$_id.key1",description: { $first: "$_id.key1" },total: {
$sum: {
$cond: {
if: { $first: [["$_id.key2"]] },then: 1,else: "$total"
}
}
},colors: {
$push: {
$cond: {
if: { $first: [["$_id.key2"]] },then: {
_id: "$_id.key2",total: "$total"
},else: "$$REMOVE"
}
}
}
}
},{ $project: { _id: 0 } }
]);
,
db.test2.aggregate([
{
$project: {
labels:1,colours: {
$filter: {
input: "$labels",as: "label",cond: {
$or: [
{$eq:["Yellow","$$label.description"]},{$eq:["Red","$$label.description"]}
]
}
}
}
}
},{$unwind:"$labels"},{$group:{
_id: "$labels.description",total: {$sum:1},colours: {$addToSet:"$colours.description"}
}},{
$project:{
_id:0,description:"$_id",total:1,colours: {
$reduce:{
input: "$colours",initialValue: [],in: {$concatArrays: ["$$value","$$this"]}
}
}
}
},{
$unwind: {
path:"$colours",preserveNullAndEmptyArrays: true
}
},{
$group:{
_id:{
description:"$description",total:"$total",colour:"$colours"
},count: {
$sum: {$cond:[{$ifNull:["$colours",false]},1,0]}
}
}
},{
$group:{
_id:{
description:"$_id.description",total:"$_id.total"
},colours: {
$push: {
$cond: [{$gt:["$count",0]},{
"_id":"$_id.colour",total:"$count"
},"$$REMOVE"
]
}
}
}
},{
$project: {
_id:0,description: "$_id.description",total: "$_id.total",colours: 1
}
}
]);
**Edit 在您的 answer 中,您缺少 Red 和 Dog 的 Yellows,因为您使用 $result
从 $arrayElemAt: ["$result.description",0]
中取出第一项。
如果描述是一种颜色,你是否也想在颜色中包括它自己的计数?
没关系,你已经更新了答案
,出于某种原因,两个答案中的代码都没有正确计算所有标签。 我正在发布有效的内容:
db.collection.aggregate([
{
$project: {
labels: 1,result: {
$filter: {
input: "$labels",cond: {
$or: [
{ $eq: ["$$label.description","Blue"] },{ $eq: ["$$label.description","Red"] },"Black-and-white"] },"Purple"] },"Orange"] },"Yellow"] },"Green"] },"Teal"] }
]
}
}
}
}
},{
$unwind: "$labels"
},{
"$group": {
_id: "$labels.description",x: {
$push: "$result.description"
},total: { "$sum": 1 }
}
},{
$project: {
x: {
$reduce: {
input: '$x',in: {$concatArrays: ['$$value','$$this']}
}
},total: 1
}
},{
$project: {
x: 1,y: { $setUnion: "$x" },{
$project: {
_id: 0,description: "$_id","colors": {
$map: {
input: "$y",in: {
_id: "$$item",count: {
$size: {
$filter: {
input: "$x",as: "itemx",cond: {
$eq: ["$$item","$$itemx"]
}
}
}
}
}
}
},{
$out: "backgrounds_meta"
}
])
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。