在我的数据库中,我在每个包含条目的文档中都有一个嵌套的元素数组,格式如下:
elements:[
{
"elem_id": 12,
items: [ {"i_id": 1, "type": x}, {"i_id": 2, "type": y}, {"i_id": 3, "type": x}]
},
{
"elem_id": 13,
items: [ {"i_id": 4, "type": x}, {"i_id": 5, "type": x}]
}
]
我试图返回具有不同类型项的所有元素,这意味着我只会返回:
{
"elem_id": 12,
items: [ {"i_id": 1, "type": x}, {"i_id": 2, "type": y}, {"i_id": 3, "type": x}]
}
因为有x和y两种类型的项
我想我需要迭代项目数组,并将数组中每个项目的类型与前一个项目的类型进行比较,但我不知道如何在聚合中做到这一点。
只是要注意-我正在使用Redash,所以我不能在查询中包含任何JS。
谢谢你的帮助!
试试这个:
db.elements.aggregate([
{ $unwind: "$elements" },
{
$addFields: {
"count": { $size: "$elements.items" },
"uniqueValues": {
$reduce: {
input: "$elements.items",
initialValue: [{ $arrayElemAt: ["$elements.items.type", 0] }],
in: {
$setUnion: ["$$value", ["$$this.type"]]
}
}
}
}
},
{
$match: {
$expr: {
$eq: ["$count", { $size: "$uniqueValues" }]
}
}
}
]);
输出:
{
"_id" : ObjectId("603f8f05bcece4372062bcea"),
"elements" : {
"elem_id" : 12,
"items" : [
{
"i_id" : 1,
"type" : 1
},
{
"i_id" : 2,
"type" : 2
},
{
"i_id" : 3,
"type" : 3
}
]
},
"count" : 3,
"uniqueValues" : [1, 2, 3]
}
你可以简化一下答案(不需要使用$reduce
或$addFields
):
db.collection.aggregate([
{$unwind: "$elements"},
{$match: {
$expr: {$gt:[
{$size: {$setIntersection: ["$elements.items.type", "$elements.items.type"]}},
1
]}
}}
])
看看它在操场的例子中是如何工作的