mongodb按位检查不返回行

时间:2015-06-12 07:19:38

标签: javascript mongodb mongodb-query

我想按位检查我的数据,但不返回data.Rights默认参数是1.如何解决这个问题?

db.getCollection('forms').find(
{ 
    "IsActive" : true, 
    "$or" : 
    [
    { "$where" :  "(this.Acls.Rights & 1) == 1" , "Acls.Actor._id" : ObjectId("5565f392a6df191eb4689bec") },
    { "$where" :  "(this.Acls.Rights & 1) == 1" , "Acls.Actor._id" : ObjectId("5565f392a6df191eb4689bed") }
    ] 
 }
)

这是我希望匹配的文件:

{ 
    "_id" : ObjectId("55686c44a6df1a1008c0b148"), 
    "IsActive" : true,
    "Acls" : [ 
        { 
            "_id" : ObjectId("557820b1a6df1a032c2c643a"), 
            "IsActive" : true,
            "Actor" : { 
                "_id" : ObjectId("5565f392a6df191eb4689bec"), 
                "IsActive" : true,
                "Name" : "admin",
                "TypeId" : 2
            }, 
            "Department" : null, 
            "Rights" : NumberLong(1)
        }
    ], 
    "AclCount" : 1
}

1 个答案:

答案 0 :(得分:0)

您的逻辑问题在于$where子句的JavaScript评估与MongoDB“本机”搜索的"dot notation"具有相同的“能力”。

因此,您需要使用JavaScript方法来评估要使用的属性的“每个”数组元素。为了做到这一点,这里使用的最佳条件是JavaScript .some()数组buit-in。如果“任意”数组元素符合您的条件,则返回true/false条件,最重要的是在没有遍历所有数组元素的情况下找到的“第一个”。

这也意味着(我不想在这里成为坏消息的承载者),你在“匹配对”中比较ObjectId的逻辑在这里不起作用。

在正常情况下,您将使用$elemMatch来确保满足特定数组元素的两个属性,但不能在$where内使用$elemMatch子句,因此所有逻辑需要使用JavaScript:

db.forms.find({
    "IsActive": true,
    "$or": [
        { "$where": "return this.Acls.some(function(el) { return ( el.Rights & 1 == 1 ) && el.Actor._id.equals(ObjectId("5565f392a6df191eb4689bec")) });"}

        { "$where": "return this.Acls.some(function(el) { return ( el.Rights & 1 == 1 ) && el.Actor._id.equals(ObjectId("5565f392a6df191eb4689bed")) });"}
     ]
})

考虑到$where的性能问题(不能对其条件使用索引),我强烈建议您在此处找到“匹配ACL”的替代方法,以使用您正在使用的“按位”方法。

是的,其他选项可能会带来更高的存储成本,但这里的权衡是,您可以使用可以直接与$elemMatch子句匹配的元素获得更快的查询结果。