Хотя существуют новые возможности, такие как MongoDB $lookup
, что делает «своего рода присоединиться», ваша конкретная операция не нуждается в этом. Все, что вы делаете здесь, возвращает результаты из другой коллекции, основанной на том, где значение _id
было привязано к предыдущему.
Для этого лучшим вариантом является выпуск один другой запрос в другой коллекции с использованием $in
.
// Mongoose turns a cursor to an array by default in the callback method
collectionOne.find(query,{ "_id": 1}).limit(limit).exec(function(err,results) {
// Just get array of _id values
var ids = results.map(function(el) { return el._id });
// Not sure if you really mean both collections have the same primary key
// I'm presuming two different fields being "id" as opposed to "_id"
collectionTwo.find({ "id": { "$in": ids } },function(err,items) {
// matching results are here
})
})
Всё.
Все, что вам сделать, это вернуть первые результаты запроса _id
значений как «список» только что, то поставить этот аргумент $in
на соответствующем поле в целевой коллекции
Если вы действительно хотели «присоединиться "и есть MongoDB 3.2 доступны, то вы можете использовать $lookup
как этот
collectionOne.aggregate([
{ "$match": query },
{ "$limit": limit },
{ "$lookup": {
"from": "collectionTwo",
"localField": "_id",
"foreignField": "id",
"as": "twoItems"
}}
])
это фактический„присоединился результат“, и, хотя вы могли возможно использовать его только возвратить совпавшие результаты от collectionTwo
, то я Persona lly не будет. Это дорогостоящее упражнение даже на сервере, и дальнейшая фильтрация, необходимая для фактического возврата этого формата, в конечном итоге будет стоить еще больше.
Вы также можете прочитать о .populate()
в mongoose, что на самом деле является «обратным» типом запроса. Вместо этого процесс состоит в том, чтобы хранить массив (или регулярное поле, но массив в этом случае) значений ObjectId
, указывающих на первичный ключ объектов в соответствующей коллекции. Поэтому, если для collectionTwo
было «много» значений, они будут храниться в массиве в пределах collectionOne
документов.
Опять же, это «эмуляция соединения», а не реальное соединение. Результат будет похож на $lookup
, и снова на самом деле не «просто» результаты от collectionTwo
, а «объединенная» версия, которую вам также необходимо будет фильтровать.
Все, что действительно происходит с .populate()
, заключается в том, что он выполняет запрос $in
в любом случае. Поэтому даже после всей работы по хранению дочерних ссылок в родительском (IMHO, в большинстве случаев, если вы можете это сделать, тогда вы можете просто вставлять данные вместо этого), фактическое взаимодействие с базой данных остается неизменным, поскольку оно все еще выполняет $in
запрос.
Вы можете использовать агрегирование с $ lookup для выполнения этой серверной части – profesor79