您可能希望处理 $all 运算符与 $not 结合的否定情况:
db.collection.find({
"images.thumbnails.size": {
"$not": { "$all": [ 150, 320, 800 ] }
}
})
可能在 MongoDB 2.6 之前的版本中,由于$all 的逻辑发生变化,您可能需要对此进行调整,但同样的事情是使用$and 构造的:
db.collection.find({
"$and": [
{ "$ne": { "images.thumbnail.size": 150 } },
{ "$ne": { "images.thumbnail.size": 320 } },
{ "$ne": { "images.thumbnail.size": 800 } }
]
})
当然请注意,这些语句匹配“文档”而不是“图像”数组的元素,以实际过滤您需要将其应用于聚合的那些:
db.collection.aggregate([
// Match the documents meeting the conditions
{ "$match": {
"images.thumbnails.size": {
"$not": { "$all": [ 150, 320, 800 ] }
}
}},
// Unwind the images array
{ "$unwind": "$images" },
// Filter out any array elements that do not match
{ "$match": {
"images.thumbnails.size": {
"$not": { "$all": [ 150, 320, 800 ] }
}
}},
// Optional: Projection re-shaping
{ "$project": {
"_id": {
"_id": "$_id",
"images": {
"name": "$images.name",
"width": "$images.width",
"height": "$images.height"
}
},
"thumbs": "$images.thumbnails"
}},
// Optional: unwind the thumbnails
{ "$unwind": "$thumbs" },
// Optional: group back only the sizes
{ "$group": {
"_id": "$_id",
"thumbs": { "$push": "$thumbs.size" }
}},
// Optional: Project with the difference on the set
{ "$project": {
"_id": "$_id._id",
"images": {
"name": "$_id.images.name",
"width": "$_id.images.width",
"height": "$_id.images.height",
"missingThumbs": { "$setDifference": [
[ 150, 320, 800 ],
"$thumbs"
]}
}
}},
// Restore the images array
{ "$group": {
"_id": "$_id",
"images": { "$push": "$images" }
}}
])
所以这使用$setDifference 更进一步,并告诉您您正在测试的哪些“缩略图大小”不存在。该阶段是可选的,因为该运算符仅适用于 MongoDB 2.6 及更高版本,因此只需删除标记为“可选:”的阶段即可过滤“图像”数组条目。
您也可以在 2.6 之前的版本中进行“差异”匹配,但这涉及的内容要多一些,但您可能想尝试解决这部分问题。
至于您的全代编辑,这里将是完整列表:
db.collection.aggregate([
// Match the documents meeting the conditions
{ "$match": {
"images.thumbnails.size": {
"$not": { "$all": [ 150, 320, 800 ] }
}
}},
// Unwind the images array
{ "$unwind": "$images" },
// Filter out any array elements that do not match
{ "$match": {
"images.thumbnails.size": {
"$not": { "$all": [ 150, 320, 800 ] }
}
}},
// Projection re-shaping
{ "$project": {
"_id": {
"_id": "$_id",
"images": {
"name": "$images.name",
"width": "$images.width",
"height": "$images.height"
}
},
"thumbs": "$images.thumbnails"
}},
// unwind the thumbnails
{ "$unwind": "$thumbs" },
// group back only the sizes
{ "$group": {
"_id": "$_id",
"thumbs": { "$push": "$thumbs.size" }
}},
// Project missingThumbs
{ "$project": {
"missingThumbs": { "$setDifference": [
[ 150, 320, 800 ],
"$thumbs"
]}
}},
// Unwind the missing thumbs
{ "$unwind": "$missingThumbs" },
// Project a size test
{ "$project": {
"missingThumbs": 1,
"larger": { "$gte": [
"$_id.images.width",
"$missingThumbs"
]}
}},
// Match the size test
{ "$match": { "larger": true }},
// Group back the missing thumbs
{ "$group": {
"_id": "$_id",
"missingThumbs": { "$push": "$missingThumbs" }
}},
// Project the images entry
{ "$project": {
"_id": "$_id._id",
"images": {
"name": "$_id.images.name",
"width": "$_id.images.width",
"height": "$_id.images.height",
"missingThumbs": "$missingThumbs"
}
}},
// Restore the images array
{ "$group": {
"_id": "$_id",
"images": { "$push": "$images" }
}}
])
这里没有什么可选的,因为您显然会使用这些功能来检测您还没有的缩略图。额外的步骤是比较丢失拇指的大小和图像的大小。任何未被检测为“更大”的内容都将被排除在外。