如果名称也等于BB或CC,我想选择所有文件,但代码以AAA开头的文件除外。
我认为下面的最后一个查询是明确的,我当然希望得到225506-125102个文档,而不是0.所以这里的结果肯定是出乎意料的。
> db.amon.find().count()
225506
> db.amon.find({code: /^AAA/, 'author.name': {'$in': ['BB', 'CC']}}).count()
125102
> db.amon.find({$not: {code: /^AAA/, 'author.name': {'$in': ['BB', 'CC']}}}).count()
0
答案 0 :(得分:6)
$not
不能仅用于反转现有表达式。
var originalSelection = {code: /^AAA/, 'author.name': {'$in': ['BB', 'CC']}}
var invalidSelection = {$not:originalSelection}
“未知的顶级运算符:$ not”
简单的解决方案是使用$nor
运算符,将表达式作为单项数组传递。
var inverseSelection = {$nor:[originalSelection]}
之所以有效,是因为单个操作数的NOR等于NOT。
答案 1 :(得分:5)
您正在运行的查询是什么,但是没有给出正确的结果?您使用的是哪个版本的MongoDB?您的$not
查询不是MongoDB 2.6中的有效查询:
> db.amon.find({ "$not" : { "code" : /^AAA/, "name" : { "$in" : ["BB", "CC"] } } })
error: {
"$err" : "Can't canonicalize query: BadValue unknown top level operator: $not",
"code" : 17287
}
这是一个做你想做的事的例子:
> db.amon.find().pretty()
{
"_id" : ObjectId("53ea66bdf9b63e0dd3ca1a18"),
"code" : "AAA",
"name" : "AA"
}
{
"_id" : ObjectId("53ea66c1f9b63e0dd3ca1a19"),
"code" : "AAA",
"name" : "BB"
}
{
"_id" : ObjectId("53ea66c3f9b63e0dd3ca1a1a"),
"code" : "AAA",
"name" : "CC"
}
{
"_id" : ObjectId("53ea66d3f9b63e0dd3ca1a1b"),
"code" : "BBB",
"name" : "AA"
}
{
"_id" : ObjectId("53ea66d6f9b63e0dd3ca1a1c"),
"code" : "BBB",
"name" : "BB"
}
{
"_id" : ObjectId("53ea66daf9b63e0dd3ca1a1d"),
"code" : "BBB",
"name" : "CC"
}
> db.amon.find({
"$or" : [
{ "code" : { "$not" : /^AAA/ } },
{ "name": { "$not" : { "$in" : ["BB", "CC"] } } }
]
})
{ "_id" : ObjectId("53ea66bdf9b63e0dd3ca1a18"), "code" : "AAA", "name" : "AA" }
{ "_id" : ObjectId("53ea66d3f9b63e0dd3ca1a1b"), "code" : "BBB", "name" : "AA" }
{ "_id" : ObjectId("53ea66d6f9b63e0dd3ca1a1c"), "code" : "BBB", "name" : "BB" }
{ "_id" : ObjectId("53ea66daf9b63e0dd3ca1a1d"), "code" : "BBB", "name" : "CC" }
写下此查询的简便方法是使用DeMorgan's Laws:交集的补充(和)是补语的并集。由于您正在搜索不满足的文档(代码是AAA)和(名称是BB或CC之一),它们满足的条件不是((代码是AAA)和(名称是BB或CC之一)) =(代码不是AAA)或(名称不是BB或CC)。
答案 2 :(得分:0)
使用$ ne或$ nin请参阅链接operators
db.amon.find().count() 225506
db.amon.find({code: /^AAA/, 'author.name': {'$in': ['BB', 'CC']}}).count() 125102
db.amon.find({$not: {code: /^AAA/, 'author.name': {'$in': ['BB', 'CC']}}}).count() 0
could be
db.amon.find({code: { $ne : /^AAA/}, 'author.name': {'$nin': ['BB', 'CC']}}}).count()
and if you want this to work as index only then create a compond index on the 2 fields
db.amon.find({code: { $ne : /^AAA/}, 'author.name': {'$nin': ['BB', 'CC']}}},{code:1,_id:0}).count()
and if you want it to work on a sharded cluster
db.amon.find({code: { $ne : /^AAA/}, 'author.name': {'$nin': ['BB', 'CC']}}},{code:1,_id:0}).explain().n
答案 3 :(得分:0)
只是通过问题陈述,我认为这个查询应该适合你:
db.amon.find({$and:[{code: {$not:/^AAA/}},{ 'author.name': {'$in': ['BB', 'CC']}}]}).count();