Mongodb $ nin查询子文档

时间:2015-04-08 08:06:56

标签: mongodb mongodb-query

以下是MongoDB的示例文档:

user: {
         _id:1,
         name:'xyz',
         age:12,
         mobile:21321312,
         transaction:[
                         {
                             trans_id:1,
                             prod:'a',
                             purchasedAt:ISODate("2015-02-01"),
                         },
                         {
                             trans_id:2,
                             prod:'b',
                             purchasedAt:ISODate("2015-02-01")
                         },
                         {
                             trans_id:3,
                             prod:'c',
                             purchasedAt:ISODate("2014-11-24")
                         }
                     ]
     }

我希望得到购买产品的用户' a'日期' 2015-02-01'但没有购买产品' b'或者' c'在同一天。所以我尝试了查询:

db.user.find({transaction:{$elemMatch:{prod:'a',purchasedAt:ISODate("2015-02-01")}}, transaction:{$elemMatch:{prod:{$nin:['b', 'c']}, purchasedAt:ISODate("2015-02-01")}}})

但查询似乎返回了错误的结果。它包含一些已购买产品的用户' c'在同一天。所以我试过了:

db.user.find({transaction:{$elemMatch:{prod:{$in:['a'], $nin:['b','c']}, purchasedAt:ISODate("2015-02-01")}}})

db.user.find({$and:[{transaction:{$elemMatch:{prod:'a',purchasedAt:ISODate("2015-02-01")}}}, {transaction:{$elemMatch:{prod:{$nin:['b', 'c']}, purchasedAt:ISODate("2015-02-01")}}}]})

但似乎都没有效果。我总是得到相同的购买日期的产品,这是$ nin部分。我也尝试了其他查询,但这些查询与上面的查询相同(例如使用点'。'运算符查询),这里提到的很简单。有没有办法得到我想要的结果?

2 个答案:

答案 0 :(得分:3)

试试这个:

db.test.find({
    "$and" : [
        { "transaction" : {
            "$elemMatch" : { "prod" : "a", "purchasedAt" : ISODate("2015-02-01") }
        } },
        { "transaction" : { "$not" : {
            "$elemMatch" : { "prod" : "b", "purchasedAt" : ISODate("2015-02-01") }
        } } },
        { "transaction" : { "$not" : {
            "$elemMatch" : { "prod" : "c", "purchasedAt" : ISODate("2015-02-01") }
        } } }
    ]
})

答案 1 :(得分:0)

您可以通过两种方式找到结果

1>使用mongo聚合

db.collectionName.aggregate({
    "$unwind": "$user.transaction"
}, {
    "$match": {
    "$and": [{
        "user.transaction.prod": "a"
    }, {
        "user.transaction.prod": {
            "$nin": ["b", "c"]
        }
    }, {
        "user.transaction.purchasedAt": ISODate("2015-02-01T00:00:00Z")
    }]
    }
}).pretty()

2 - ;使用find with projection

    db.collectionName.find({
    "user.transaction.prod": "a",
    "user.transaction.purchasedAt": ISODate("2015-02-01T00:00:00Z")
    },
    {
    "user.transaction.$": 1
    }).pretty()