我正在尝试使用MongoDB否定$and
子句,并且我收到了MongoError: invalid operator: $and
消息。基本上我想要实现的目标如下:
query = { $not: { $and: [{institution_type:'A'}, {type:'C'}] } }
这可以在mongo查询中表达吗?
以下是一个示例集合:
{ "institution_type" : "A", "type" : "C" }
{ "institution_type" : "A", "type" : "D" }
{ "institution_type" : "B", "type" : "C" }
{ "institution_type" : "B", "type" : "D" }
我想要回复的内容如下:
{ "institution_type" : "A", "type" : "D" }
{ "institution_type" : "B", "type" : "C" }
{ "institution_type" : "B", "type" : "D" }
答案 0 :(得分:18)
您正在寻找NOT (A AND C)
,相当于NOT A OR NOT C
:
db.collection.find({
"$or": [
{"institution_type": {"$ne": "A"}},
{"type": {"$ne": "C"}}
]
})
MongoDB还有一个$nor逻辑运算符,它“对一个或多个查询表达式的数组执行逻辑NOR运算,并选择使数组中所有查询表达式失败的文档”,因此等效查询将是:
db.collection.find({
"$nor": [
{"institution_type": "A"},
{"type": "C"}
]
})
接受的答案建议使用$where
运算符,但这里不需要这样做,并且还有税收效果。
答案 1 :(得分:1)
我看不到标准否定,您需要使用JavaScript进行$where
运算符样式的查询:
db.collection.find(function(){
return !( this.institution_type == "A" && this.type == "C" )
})
不是最好的扫描整个集合,但逻辑上的否定需要这个,因为你需要测试这两个值。
或基本等效的聚合操作:
db.collection.aggregate([
{ "$project": {
"institution_type": 1,
"type": 1,
"notmatched": {
"$not": {
"$and": [
{ "eq": [ "$institution_type", "A" ] },
{ "eq": [ "$type", "C" ] }
]
}
}
}},
{ "$match": {
"notmatched": true
}}
])
只是通过在内部包含否定来实现这也是一种有效的形式:
db.collection.find({
"$or": [
{ "institution_type": { "$ne": "A" } },
{ "type": { "$ne": "C" }},
]
})
这基本上否定了" A"和" C"在同一文档中,就像其他逻辑与包装一样#34;不是"条件。
在MongoDB查询中,$and
实际上是隐式的,因为这是查询中术语的默认比较。当您在同一领域寻找多个条件时,您只需要使用$and
。
但您的查询是一个简单的不等式匹配:
db.collection.find({
"institution_type": { "$ne": "bank" },
"type": { "$ne": "account_type" }
})
因此,您使用$ne
运算符来否定匹配项中的条款,如前所述,$and
是隐式的,因此必须同时适用这两个条件。
所以使用样本数据:
{ "institution_type" : "bank", "type" : "account_type" }
{ "institution_type" : "school", "type" : "account_type" }
{ "institution_type" : "school", "type" : "account" }
查询仅返回不符合这两个条件的行:
{ "institution_type" : "school", "type" : "account" }
你的评论说你想要"或"当您使用" AND"时未在查询中指定,所以也许您期望" OR"是隐含的,与我告诉你的情况相反。
需要明确应用$or
条件:
db.collection.find({
"$or": [
{ "inititution_type": { "$ne": "bank" } },
{ "type": { "$ne": "account_type" } }
]
})
这实际上是双重否定并将返回所有结果。
也许你的意思是$nor
:
db.data.find({
"$nor": [
{ "inititution_type": "bank" },
{ "type": "account_type" }
]
})
但实际上这与我给你的第一个查询在逻辑上相同。
答案 2 :(得分:0)
我有一个相同的问题,但没有解决。
我的收藏有以下内容(总计17 ):
{
"_id" : ObjectId("5d9d09dff9399554b35f4fc8"),
"status" : {
"codigo" : "1",
"msg" : "Ativo"
},
"extra" : [
],
"tipo" : "amizade",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d69a8eb0215c92942fd0983")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d6821c70215c9e5e5fd096b")
},
"createdAt" : ISODate("2019-10-08T22:12:47.872+0000"),
"updatedAt" : ISODate("2019-10-08T22:12:47.872+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9d09dff9399553df5f4fc9"),
"status" : {
"codigo" : "1",
"msg" : "Ativo"
},
"extra" : [
],
"tipo" : "amizade",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d6821c70215c9e5e5fd096b")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d69a8eb0215c92942fd0983")
},
"createdAt" : ISODate("2019-10-08T22:12:47.883+0000"),
"updatedAt" : ISODate("2019-10-08T22:13:10.129+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9d0a00f93995da635f4fca"),
"status" : {
"codigo" : "1",
"msg" : "Ativo"
},
"extra" : [
],
"tipo" : "vacuo",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d69a8eb0215c92942fd0983")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d6821c70215c9e5e5fd096b")
},
"createdAt" : ISODate("2019-10-08T22:13:20.310+0000"),
"updatedAt" : ISODate("2019-10-08T22:13:20.310+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9d0a44de4e534ba8a1eaf6"),
"status" : {
"codigo" : "1",
"msg" : "Ativo"
},
"extra" : [
],
"tipo" : "nao-sugerir",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d69a8eb0215c92942fd0983")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d833a2a7aebc4af5ba378ca")
},
"createdAt" : ISODate("2019-10-08T22:14:28.445+0000"),
"updatedAt" : ISODate("2019-10-08T22:14:28.445+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9d0a48de4e534ba8a1eaf7"),
"status" : {
"codigo" : "1",
"msg" : "Ativo"
},
"extra" : [
],
"tipo" : "nao-sugerir",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d6821c70215c9e5e5fd096b")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d82c2e07aebc4305da378b1")
},
"createdAt" : ISODate("2019-10-08T22:14:32.189+0000"),
"updatedAt" : ISODate("2019-10-08T22:14:32.189+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9d0b28de4e534ba8a1eaf8"),
"status" : {
"codigo" : "1",
"msg" : "Ativo"
},
"extra" : [
],
"tipo" : "amizade",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d6821c70215c9e5e5fd096b")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d82de827aebc42767a378c6")
},
"createdAt" : ISODate("2019-10-08T22:18:16.235+0000"),
"updatedAt" : ISODate("2019-10-08T22:18:16.235+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9d0b28de4e534ba8a1eaf9"),
"status" : {
"codigo" : "2",
"msg" : "Solicitação pendente"
},
"extra" : [
],
"tipo" : "amizade",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d82de827aebc42767a378c6")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d6821c70215c9e5e5fd096b")
},
"createdAt" : ISODate("2019-10-08T22:18:16.268+0000"),
"updatedAt" : ISODate("2019-10-08T22:18:16.268+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9d10eede4e534ba8a1eb0d"),
"status" : {
"codigo" : "1",
"msg" : "Ativo"
},
"extra" : [
],
"tipo" : "amizade",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d6821c70215c9e5e5fd096b")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d82755c7aebc49efca378aa")
},
"createdAt" : ISODate("2019-10-08T22:42:54.790+0000"),
"updatedAt" : ISODate("2019-10-08T22:42:54.790+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9d10eede4e534ba8a1eb0e"),
"status" : {
"codigo" : "2",
"msg" : "Solicitação pendente"
},
"extra" : [
],
"tipo" : "amizade",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d82755c7aebc49efca378aa")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d6821c70215c9e5e5fd096b")
},
"createdAt" : ISODate("2019-10-08T22:42:54.822+0000"),
"updatedAt" : ISODate("2019-10-08T22:42:54.822+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9dad94f939952d305f4fcc"),
"status" : {
"codigo" : "1",
"msg" : "Ativo"
},
"extra" : [
],
"tipo" : "amizade",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d69a8eb0215c92942fd0983")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d82d8fa7aebc42be1a378c2")
},
"createdAt" : ISODate("2019-10-09T09:51:16.984+0000"),
"updatedAt" : ISODate("2019-10-09T09:51:16.984+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9dad94f939957a905f4fcd"),
"status" : {
"codigo" : "2",
"msg" : "Solicitação pendente"
},
"extra" : [
],
"tipo" : "amizade",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d82d8fa7aebc42be1a378c2")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d69a8eb0215c92942fd0983")
},
"createdAt" : ISODate("2019-10-09T09:51:16.998+0000"),
"updatedAt" : ISODate("2019-10-09T09:51:16.998+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9dad96f939956a345f4fce"),
"status" : {
"codigo" : "1",
"msg" : "Ativo"
},
"extra" : [
],
"tipo" : "vacuo",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d69a8eb0215c92942fd0983")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d82d8fa7aebc42be1a378c2")
},
"createdAt" : ISODate("2019-10-09T09:51:18.587+0000"),
"updatedAt" : ISODate("2019-10-09T09:51:18.587+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9dce0cf939958be25f4fcf"),
"status" : {
"codigo" : "1",
"msg" : "Ativo"
},
"extra" : [
],
"tipo" : "amizade",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d69a8eb0215c92942fd0983")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d8354497aebc439a7a378d0")
},
"createdAt" : ISODate("2019-10-09T12:09:48.619+0000"),
"updatedAt" : ISODate("2019-10-09T12:09:48.619+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9dce0cf939958c4b5f4fd0"),
"status" : {
"codigo" : "2",
"msg" : "Solicitação pendente"
},
"extra" : [
],
"tipo" : "amizade",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d8354497aebc439a7a378d0")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d69a8eb0215c92942fd0983")
},
"createdAt" : ISODate("2019-10-09T12:09:48.635+0000"),
"updatedAt" : ISODate("2019-10-09T12:09:48.635+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9dce10f9399590a65f4fd1"),
"status" : {
"codigo" : "1",
"msg" : "Ativo"
},
"extra" : [
],
"tipo" : "amizade",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d69a8eb0215c92942fd0983")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d685f790215c983e4fd097e")
},
"createdAt" : ISODate("2019-10-09T12:09:52.994+0000"),
"updatedAt" : ISODate("2019-10-09T12:09:52.994+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9dce11f9399564715f4fd2"),
"status" : {
"codigo" : "2",
"msg" : "Solicitação pendente"
},
"extra" : [
],
"tipo" : "amizade",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d685f790215c983e4fd097e")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d69a8eb0215c92942fd0983")
},
"createdAt" : ISODate("2019-10-09T12:09:53.006+0000"),
"updatedAt" : ISODate("2019-10-09T12:09:53.006+0000"),
"__v" : NumberInt(0)
}
// ----------------------------------------------
{
"_id" : ObjectId("5d9e4afbde4e534ba8a1eb0f"),
"status" : {
"codigo" : "1",
"msg" : "Ativo"
},
"extra" : [
],
"tipo" : "nao-sugerir",
"vinculo" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d69a8eb0215c92942fd0983")
},
"vinculado" : {
"colecao" : "atletas",
"objeto" : ObjectId("5d80f31e7aebc412dea3789a")
},
"createdAt" : ISODate("2019-10-09T21:02:51.026+0000"),
"updatedAt" : ISODate("2019-10-09T21:02:51.026+0000"),
"__v" : NumberInt(0)
}
在此查询中,返回正确的( 4 itens ):
db.getCollection("vinculos").aggregate(
[
{
"$match" : {
"status.codigo" : "1",
"tipo" : {
"$in" : [
"amizade",
"nao-sugerir"
]
},
"vinculo.objeto" : ObjectId("5d6821c70215c9e5e5fd096b")
}
}
]
)
但是我需要反过来:
第一次尝试(无结果):
db.getCollection("vinculos").aggregate(
[
{
"$match" : {
"$nor" : [
{
"status.codigo" : "1"
},
{
"tipo" : {
"$in" : [
"amizade",
"nao-sugerir"
]
}
},
{
"vinculo.objeto" : ObjectId("5d6821c70215c9e5e5fd096b")
}
]
}
}
]
)
第二次尝试(无结果):
db.getCollection("vinculos").aggregate(
[
{
"$match" : {
"$and" : [
{
"status.codigo" : {
"$ne" : "1"
}
},
{
"tipo" : {
"$nin" : [
"amizade",
"nao-sugerir"
]
}
},
{
"vinculo.objeto" : {
"$ne" : ObjectId("5d6821c70215c9e5e5fd096b")
}
}
]
}
}
]
)
我需要退回另外13个车票,有什么建议吗?
答案 3 :(得分:0)
db.getCollection('test').find({ $or: [ {institution_type:{$ne:'A'}}, {type:{$ne:'C'}} ]})
...然后,谢谢(支持)this answer(不是我)
db.getCollection('test').find({ $nor: [{institution_type:'A', type:'C'}] })
我在MongoDB中找不到logical operator来处理$nand
逻辑,因此我“构建”了该逻辑(见下文)。
$nand
运算符有一个open feature request,但我不会屏住呼吸(创建于2014年)。
$nor
逻辑, $ne
也可以做您想做的事情。
(但是IMO-感觉像我们是在反正行为-仅使用反$not
的行为,而无视数组的$and
行为...但是它起作用了,所以不是错误)。
db.getCollection('test').insertMany([
{ "institution_type" : "A", "type" : "C" },
{ "institution_type" : "A", "type" : "D" },
{ "institution_type" : "B", "type" : "C" },
{ "institution_type" : "B", "type" : "D" }
])
// "NAND gate": (NOT A) OR (NOT B) -> correct 3x results
db.getCollection('test').find({ $or: [ {institution_type:{$not:{$eq:'A'}}}, {type:{$not:{$eq:'C'}}} ]})
// or simpler...
db.getCollection('test').find({ $or: [ {institution_type:{$ne:'A'}}, {type:{$ne:'C'}} ]})
// or simpler still...
// "NOR gate": (NOT A) AND (NOT B) -> correct 3x results
db.getCollection('test').find({ $nor: [{institution_type:'A', type:'C'}] })