Mongodb$nin查询子文档
Mongodb $nin querying sub-document
这是我的示例文档 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")
}
]
}
我想获取在日期“2015-02-01”购买了产品 'a' 但在同一天未购买产品 '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")}}})
但是查询好像return错误的结果。它包含一些在同一天购买了产品 '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")}}}]})
但 none 似乎有效。我总是得到具有相同购买日期的产品,即 $nin 部分。我也尝试过其他查询,但这些查询与上面的查询类型相同(例如使用点“.”运算符进行查询)并且在这里提及是微不足道的。有什么办法可以得到我想要的结果吗?
您可以通过以下两种方式找出结果
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> 将查找与投影结合使用
db.collectionName.find({
"user.transaction.prod": "a",
"user.transaction.purchasedAt": ISODate("2015-02-01T00:00:00Z")
},
{
"user.transaction.$": 1
}).pretty()
试试这个:
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") }
} } }
]
})
这是我的示例文档 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")
}
]
}
我想获取在日期“2015-02-01”购买了产品 'a' 但在同一天未购买产品 '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")}}})
但是查询好像return错误的结果。它包含一些在同一天购买了产品 '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")}}}]})
但 none 似乎有效。我总是得到具有相同购买日期的产品,即 $nin 部分。我也尝试过其他查询,但这些查询与上面的查询类型相同(例如使用点“.”运算符进行查询)并且在这里提及是微不足道的。有什么办法可以得到我想要的结果吗?
您可以通过以下两种方式找出结果
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> 将查找与投影结合使用
db.collectionName.find({
"user.transaction.prod": "a",
"user.transaction.purchasedAt": ISODate("2015-02-01T00:00:00Z")
},
{
"user.transaction.$": 1
}).pretty()
试试这个:
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") }
} } }
]
})