我有一个类似以下的集合,目标是删除与其items.fruits.color
和items.fruits.type
相匹配的每个文档
问题是,我需要找到同时具有两个条件的水果。
此外,如果items
键为空,我需要选择该文档
这是我聚合的状态:
{
type: "x"
color: "red"
items => [
{
item_id: 6
fruits: [
{
color: "red",
type: "x"
},
{
color: "red",
type: "y"
}
]
},
{
item_id: 7
fruits: [
{
color: "orange",
ref_id: "h"
},
{
color: "green",
ref_id: "x"
}
]
}
]
},{
type: "o"
color: "red"
items => []
},{
type: "w"
color: "red"
items => [
{
fruits: [
{
type: "w",
color: "black"
}
]
}
]
}
因此第一个文档无效,因为items[fruits][0]
的属性完全匹配。
但是第二个有效,因为items数组为空。
第三个也是有效的,因为其中没有匹配的水果。
我尝试的最后一个查询是:
$match: {
"items.fruits": {
$not: {
$elemMatch: {
color: "$color",
type: "$type"
}
}
}
}
但是它不起作用。而是显示所有文档。 (我认为这是因为$ color语句未被识别为变量)
答案 0 :(得分:1)
如果要在没有具有给定颜色和类型的水果的任何文档上进行匹配,这应该起作用:
[{$match: {
"items.fruits": {
$not: {
$elemMatch: {
color: "red",
type: "x"
}
}
}
}}]
答案 1 :(得分:1)
我朝着另一个方向前进。我认为这可以帮助您入门,您可以添加其他$ project或$ group阶段以所需的格式获得最终结果。
[
{$unwind: {
path: "$items"
}},
{$unwind: {
path: "$items.fruits"
}},
{$addFields: {
"items.fruits.isAMatch":
{ $and: [
{$eq: ["$items.fruits.type", "$type"] },
{$eq: ["$items.fruits.color", "$color"] }
]
}
}},
{$group: {
_id:
{"id": "$_id",
"itemid": "$items.item_id"
},
type: {$first: "$type"},
color: {$first: "$color"},
fruits: { $push: "$items.fruits" }
}}, {}]
第一阶段展开items数组。第二阶段展开水果数组。第三阶段检查水果和颜色是否匹配,并创建一个名为isAMatch
的新字段以指示它们是否匹配。最后阶段根据_id和items.item_id将文档重新组合在一起。这些文档类似于原始文档,但是它们在Fruits数组对象中添加了字段,指示它们是否匹配。