MongoDB, использующий NOT и AND вместе
Я пытаюсь отрицать предложение $and
с MongoDB, и я получаю сообщение 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" }
Ответы
Ответ 1
Вы ищете NOT (A AND C)
, что эквивалентно NOT A OR NOT C
:
db.collection.find({
"$or": [
{"institution_type": {"$ne": "A"}},
{"type": {"$ne": "C"}}
]
})
MongoDB также имеет $или логический оператор, который "выполняет логическую операцию NOR в массиве одного или нескольких выражений запроса и выбирает документы что не все выражения запроса в массиве", поэтому эквивалентный запрос будет выглядеть следующим образом:
db.collection.find({
"$nor": [
{"institution_type": "A"},
{"type": "C"}
]
})
В принятом ответе рекомендуется использовать оператор $where
, но это необязательно здесь и эффективность налогов.
Ответ 2
Не стандартное отрицание, которое я вижу, вам понадобится $where
с помощью JavaScript
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" в том же документе, как и другая логика с условием "нет".
Orig
В запросах 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" }
В вашем комментарии говорится, что вы используете "ИЛИ", который вы не указываете в своем запросе, когда используете "И", поэтому, возможно, вы ожидаете, что "ИЛИ" является неявным, что является противоположностью того, что я сказал вам, это случай.
$or
условие должно быть явно применено:
db.collection.find({
"$or": [
{ "inititution_type": { "$ne": "bank" } },
{ "type": { "$ne": "account_type" } }
]
})
Это фактически двойное отрицание и вернет все результаты.
Возможно, вы имеете в виду $nor
:
db.data.find({
"$nor": [
{ "inititution_type": "bank" },
{ "type": "account_type" }
]
})
Но на самом деле это логически то же самое, что и первый запрос, который я вам дал.
Ответ 3
У меня та же проблема, но она не решена.
У моей коллекции есть эти itens (всего 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")
}
}
]
)
Но мне нужно обратное к этому itens:
1-я попытка (без результатов):
db.getCollection("vinculos").aggregate(
[
{
"$match" : {
"$nor" : [
{
"status.codigo" : "1"
},
{
"tipo" : {
"$in" : [
"amizade",
"nao-sugerir"
]
}
},
{
"vinculo.objeto" : ObjectId("5d6821c70215c9e5e5fd096b")
}
]
}
}
]
)
2-я попытка (без результатов):
db.getCollection("vinculos").aggregate(
[
{
"$match" : {
"$and" : [
{
"status.codigo" : {
"$ne" : "1"
}
},
{
"tipo" : {
"$nin" : [
"amizade",
"nao-sugerir"
]
}
},
{
"vinculo.objeto" : {
"$ne" : ObjectId("5d6821c70215c9e5e5fd096b")
}
}
]
}
}
]
)
Мне нужно будет вернуть еще 13 итенов, есть предложения?