У меня есть две коллекции MongoDB, которые имеют общий _id.Используя оболочку mongo, я хочу найти все документы в одной коллекции, у которых нет совпадающего _id в другой коллекции.
Пример:
> db.Test.insert({ "_id" : ObjectId("4f08a75f306b428fb9d8bb2e"), "foo" : 1 })
> db.Test.insert({ "_id" : ObjectId("4f08a766306b428fb9d8bb2f"), "foo" : 2 })
> db.Test.insert({ "_id" : ObjectId("4f08a767306b428fb9d8bb30"), "foo" : 3 })
> db.Test.insert({ "_id" : ObjectId("4f08a769306b428fb9d8bb31"), "foo" : 4 })
> db.Test.find()
{ "_id" : ObjectId("4f08a75f306b428fb9d8bb2e"), "foo" : 1 }
{ "_id" : ObjectId("4f08a766306b428fb9d8bb2f"), "foo" : 2 }
{ "_id" : ObjectId("4f08a767306b428fb9d8bb30"), "foo" : 3 }
{ "_id" : ObjectId("4f08a769306b428fb9d8bb31"), "foo" : 4 }
> db.Test2.insert({ "_id" : ObjectId("4f08a75f306b428fb9d8bb2e"), "bar" : 1 });
> db.Test2.insert({ "_id" : ObjectId("4f08a766306b428fb9d8bb2f"), "bar" : 2 });
> db.Test2.find()
{ "_id" : ObjectId("4f08a75f306b428fb9d8bb2e"), "bar" : 1 }
{ "_id" : ObjectId("4f08a766306b428fb9d8bb2f"), "bar" : 2 }
Теперь я хочу запрос или запросыкоторый возвращает два документа в Test, где _id не соответствуют ни одному документу в Test2:
{ "_id" : ObjectId("4f08a767306b428fb9d8bb30"), "foo" : 3 }
{ "_id" : ObjectId("4f08a769306b428fb9d8bb31"), "foo" : 4 }
Я пробовал различные комбинации $ not, $ ne, $ или, $ in, но просто не могуполучить правильную комбинацию и синтаксис.Кроме того, я не против, если сначала выполняется db.Test2.find({}, {"_id": 1})
, сохраняемый в некоторой переменной, которая затем используется во втором запросе (хотя я не могу заставить это работать также).
Обновление : ответ Захария, указывающий на нин, ответил на ключевую часть вопроса.Например, это работает:
> db.Test.find({"_id": {"$nin": [ObjectId("4f08a75f306b428fb9d8bb2e"), ObjectId("4f08a766306b428fb9d8bb2f")]}})
{ "_id" : ObjectId("4f08a767306b428fb9d8bb30"), "foo" : 3 }
{ "_id" : ObjectId("4f08a769306b428fb9d8bb31"), "foo" : 4 }
Но (и признание того, что это не масштабируемо, но в любом случае пытаюсь сделать это, потому что это не проблема в этой ситуации), я все еще не могу объединить два запроса вместе в оболочке,Это самое близкое, что я могу получить, что явно не идеально:
vals = db.Test2.find({}, {"_id": 1}).toArray()
db.Test.find({"_id": {"$nin": [ObjectId(vals[0]._id), ObjectId(vals[1]._id)]}})
Есть ли способ вернуть только значения в команде поиска, чтобы vals можно было использовать непосредственно как вход массива для $нин