Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 匹配子数组特定元素中的两个值_Mongodb - Fatal编程技术网

Mongodb 匹配子数组特定元素中的两个值

Mongodb 匹配子数组特定元素中的两个值,mongodb,Mongodb,我有这样的记录: { "_id" : ObjectId("5864b5d03ff9b7ad4c5eaf2f"), "userId" : ObjectId("967de01f640b7e4729b49fce"), "_children" : { "usersCategories" : [ { "categoryId" : ObjectId("4bafbe0678081f8a40cae944"),

我有这样的记录:

  {      
    "_id" : ObjectId("5864b5d03ff9b7ad4c5eaf2f"),
    "userId" : ObjectId("967de01f640b7e4729b49fce"),
    "_children" : {
      "usersCategories" : [
        {
          "categoryId" : ObjectId("4bafbe0678081f8a40cae944"),
          "status" : "GRANTED"
        },
        {
          "categoryId" : ObjectId("0d538c05c3f98b1921426d97"),
          "status" : "APPLIED"
        }
      ]
    }
  }
记录的合理性很简单:每个用户可以附加几个类别,这些类别可以“授予”或“应用”。 在这种情况下,用户申请了类别
0d538c05c3f98b1921426d97
,但尚未获得批准

现在,问题来了。我想要一个与该类别匹配并获得批准的用户列表。此外,我还想确保如果
userId
与特定值(将设置为查询者)匹配,则无论类别的状态如何,都会返回该类别。其想法是,记录所有者不应该有基于状态的过滤器

(注意:我意识到以下问题是错误的。)

因此,如果用户
000000000000000000000000000000
进行查询:

 { '$and': 
    [ 
      { '_children.usersCategories.categoryId': ObjectId('0d538c05c3f98b1921426d97') },
      { '$or': 
        [ 
          { '_children.usersCategories.status': 'GRANTED' },
          { userId: ObjectId('000000000000000000000000') } 
        ] 
      } 
    ] 
  }
 { '$and': 
    [ 
      { '_children.usersCategories.categoryId': ObjectId('0d538c05c3f98b1921426d97') },
      { '$or': 
        [ 
          { '_children.usersCategories.status': 'GRANTED' },
          { userId: ObjectId('967de01f640b7e4729b49fce') } 
        ] 
      } 
    ] 
  }
如果用户
967de01f640b7e4729b49fce
进行查询:

 { '$and': 
    [ 
      { '_children.usersCategories.categoryId': ObjectId('0d538c05c3f98b1921426d97') },
      { '$or': 
        [ 
          { '_children.usersCategories.status': 'GRANTED' },
          { userId: ObjectId('000000000000000000000000') } 
        ] 
      } 
    ] 
  }
 { '$and': 
    [ 
      { '_children.usersCategories.categoryId': ObjectId('0d538c05c3f98b1921426d97') },
      { '$or': 
        [ 
          { '_children.usersCategories.status': 'GRANTED' },
          { userId: ObjectId('967de01f640b7e4729b49fce') } 
        ] 
      } 
    ] 
  }
删除“所有者过滤器”后,查询可以简化(并且仍然是中断的):

明显的问题是,
$和
将匹配完整记录。因此,无论
\u children.usersCategories.categoryId
\u children.usersCategories.status
是否在
\u children.usersCategories
的两个不同元素中找到匹配项,记录都将匹配

然而,这个想法是将子记录作为一个整体进行匹配。我意识到简单的解决方案是:

  { '$and': 
     [ 
       { '_children.usersCategories' : 
         {
           'categoryId': ObjectId('0d538c05c3f98b1921426d97'),
           'status': 'GRANTED' 
          }
        }
     ]

   }
问题:

  • 这个最新的表单是Mongo中确保所有条件都与文档中的一个子元素匹配的唯一方法吗

  • 如果是,那么像这样的查询如何:“所有具有子记录的记录,其中ID为0d538c05c3f98b1921426d97且状态为
    已授予
    或标志
    alwaysOn
    为真”

如果您同意将数据结构更新到下面,则可以使用投影运算符匹配第一个完整的子记录

{
    "_id": ObjectId("5864b5d03ff9b7ad4c5eaf2f"),
    "userId": ObjectId("967de01f640b7e4729b49fce"),
    "usersCategories": [{
        "categoryId": ObjectId("4bafbe0678081f8a40cae944"),
        "status": "GRANTED"
    }, {
        "categoryId": ObjectId("0d538c05c3f98b1921426d97"),
        "status": "APPLIED"
    }]
}
所以你可以用这样的方法:

db.collection.find({}, {
    'usersCategories': {
        $elemMatch: {
            'categoryId': ObjectId('4bafbe0678081f8a40cae944'),
            'status': 'GRANTED'
        }
    }
})
对于第二部分,您可以尝试以下内容

db.collection.find({
    '$and': [{
        'usersCategories.categoryId': ObjectId('4bafbe0678081f8a40cae944'),
        {
            $or: {
                'usersCategories.status': 'GRANTED',
                'usersCategories.alwaysOn': true
            }
        }
    }]
})