Подтвердить что ты не робот

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" }
4b9b3361

Ответ 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 итенов, есть предложения?