我有与此类似的对象集合(为了解决这个问题而进行了简化):
_id: '6509e5f504613ddc1d92c62f',
matchingHistory: [
{
color: 'red',
shape: 'square',
size: 'large'
},
{
color: 'red',
shape: 'square',
size: 'small'
},
]
我想从
find
查询中排除 matchingHistory
中没有 red
、square
和 large
对象的所有文档,但所有且仅所有这些条件必须匹配。 matchingHistory
最初未设置,稍后重置时它会变成空数组,因此这些文档应包含在结果中。太长了;我只想排除对象数组中包含精确对象(红色+方形+大)的文档。
我尝试了
$not
、$nor
的多种组合,但没有产生预期的结果。
我的最后一次尝试是下面的,但问题是,它实际上还排除了“red + square + small”(因为它似乎关心“至少”一个属性匹配:
$or: [
{
matchingHistory: {
$exists: true,
$eq: [],
},
},
{
matchingHistory: {
$exists: false,
},
},
{
$and: [
{
matchingHistory.color: {
$ne: 'red',
},
},
{
matchingHistory.shape: {
$ne: 'square',
},
},
{
matchingHistory.size: {
$ne: 'large',
},
},
],
}
]
这是一个相当简单的发现。想象一下,您想要找到带有
matchingHistory
的文档,该文档在其数组中有一个与{ color: 'red', shape: 'square', size: 'large'}
匹配的对象,然后像这样否定它:
db.collection.find({
$or: [
{
matchingHistory: {
$exists: true,
$eq: []
}
},
{
matchingHistory: {
$exists: false
}
},
{
matchingHistory: {
$not: { //< All important not
$elemMatch: { //< Exact element match
color: "red",
shape: "square",
size: "large"
}
}
}
}
]
})
查看它的工作情况在这里