考虑此收藏集:
{
{ name: 'first', toys: ['doll', 'car', 'doll'],
{ name: 'second', toys: ['doll', 'car'],
{ name: 'third', toys: ['doll', 'car', 'bricks'],
{ name: 'fourth', toys: ['doll', 'bricks'],
{ name: 'fifth', toys: []
}
我想查询toys
字段是仅包含doll
和car
的数组的文档。在这种情况下,first
和second
应该匹配。 first
之所以匹配,是因为doll
和car
可以在数组中重复,third
不匹配,因为数组中必须没有其他值,并且{{1} }和fourth
不匹配,因为它们不同时包含fifth
和doll
。
使用car
和$all
对我不起作用,因为它们与$in
相匹配。我该如何实现?谢谢!
答案 0 :(得分:2)
一种更好的方法是使用聚合运算符$setEquals
,该运算符比较两个或多个数组,如果它们具有相同的不同元素,则返回true,否则返回false:
db.collection.find({
'$expr': {
'$setEquals': ['$toys', ['doll', 'car']]
}
})
另一种选择是$setDifference
,它采用两个数组并相对于第一个数组执行第二个数组的相对补数,并且此操作不需要元素顺序。
在您的情况下,请使用$setDifference
中的结果来检查其是否为空并将其设置为查询的基础。
例如操作
{ $setDifference: [ ['doll', 'car', 'doll'], ['doll', 'car'] ] } => []
还有这个
{ $setDifference: [ ['car', 'doll', 'doll'], ['doll', 'car'] ] } => []
以及
{ $setDifference: [ ['car', 'doll'], ['doll', 'car'] ] } => []
或
{ $setDifference: [ ['doll', 'car'], ['doll', 'car'] ] } => []
但是
{ $setDifference: [ ['doll', 'car', 'bricks'], ['doll', 'car'] ] } => ['bricks']
使用上面的逻辑,作为帮助者,您可以使用$size
来获取数组结果的长度,并使用$expr
来检查查询表达式的长度是否为0
最终查询:
db.collection.find({
'$expr': {
'$eq': [
{ '$size': {
'$setDifference': [
'$toys',
['doll', 'car']
]
} },
0
]
}
})
答案 1 :(得分:0)
以下查询检索文档是否具有car
或doll
或两者都有。但是它不会检索空数组记录。
db.getCollection('toys').find({
$and: [{
toys: {$elemMatch: {$in: ["doll", "car"]}}
},
{
toys: {$not: {$elemMatch: {$nin: ["doll", "car"]}}}
}]})