MongoDb查询$ nin无法从文档数组中读取

时间:2016-02-26 09:21:20

标签: arrays node.js mongodb mongodb-query

我已经提供了一个名为votes的集合,其中包含基于此设计的文档:

{
    "_id" : ObjectId("56c000000000000001"),
    "timestamp" : 1456441690,
    "filename" : "42598295724057245724579",
    "phoneNumber" : 49123456789,
    "phoneNumberVotes" : [ 
        49123456783,
        49123456784
    ]
}

phoneNumberVotes数组可以为空。

我正在尝试执行此查询:

db.getCollection('votes').find
(
    {
        $and:[
            { phoneNumber: { $ne: 49123456789}},
            { phoneNumber: { $nin: phoneNumberVotes }}
        ]
    },
    { timestamp: 1, filename: 1, phoneNumber: 1, phoneNumberVotes: 1}
)

但这不起作用。当我尝试在查询中“手动”创建一个数组时,它可以工作,例如:

db.getCollection('votes').find
(
    {
        $and:[
            { phoneNumber: { $ne: 49123456789}},
            { phoneNumber: { $nin: [49123456783,49123456784] }}
        ]
    },
    { timestamp: 1, filename: 1, phoneNumber: 1, phoneNumberVotes: 1}
)

我尝试使用的方法有什么问题?谢谢你的帮助!

1 个答案:

答案 0 :(得分:2)

您无法直接比较字段。 Documentation中的<field><value>之间存在差异。

在您的情况下,您需要使用$where运算符来执行javascript:

db.votes.find
(
    {
        phoneNumberVotes:{$exists:true},
        phoneNumber:{$exists:true, $ne:"49123456789"},
        $where: 'this.phoneNumberVotes.indexOf(this.phoneNumber) < 0'
    },
    { timestamp: 1, filename: 1, phoneNumber: 1, phoneNumberVotes: 1}
)

它适用于标量值。

您正在使用NumberLong的数字。有一个old bug与对象比较相关,因此您需要将电话号码转换为字符串:

db.votes.find
(
    {
        phoneNumberVotes:{$exists:true},
        phoneNumber:{$exists:true, $ne:49123456789},
        $where: 'this.phoneNumberVotes.map(function(n){return n + ""}).indexOf(this.phoneNumber + "") < 0'
    },
    { timestamp: 1, filename: 1, phoneNumber: 1, phoneNumberVotes: 1}
)

它可能很慢,因此将电话号码转换为数据库中的字符串可能是值得的,而不是运行时。