首页 > 解决方案 > 查找具有仅包含特定值而没有其他内容的数组字段的文档

问题描述

考虑这个集合:

{
  { 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字段是仅包含dolland的数组的文档car。在这种情况下,两者firstsecond应该匹配。first匹配是因为dollandcar可以在数组中重复,third不匹配是因为数组中不能存在其他值,fourthandfifth不匹配是因为它们不包含dolland car

使用$alland$in对我不起作用,因为它们匹配third. 我怎样才能做到这一点?谢谢!

标签: mongodbmongoose

解决方案


更好的方法是使用聚合运算符$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并检查它是否为 0 用于您的查询表达式$expr


最终查询:

db.collection.find({
    '$expr': {
        '$eq': [
            { '$size': { 
                '$setDifference': [ 
                    '$toys', 
                    ['doll', 'car'] 
                ] 
            } },
            0
        ]
    }
})

推荐阅读