#node.js #mongodb #mongoose #mean-stack #mongoose-schema
#node.js #mongodb #mongoose #средний стек #mongoose-схема
Вопрос:
У меня возникла проблема, и мне не удалось найти то, что я точно ищу. у меня есть эта Ads
схема и со ссылками на другие:
link: {
type: String,
default: 'n/a',
},
page: {
type: mongoose.Schema.ObjectId,
ref: 'AdsPage',
required: true,
},
slot: {
type: mongoose.Schema.ObjectId,
ref: 'AdsSlot',
required: true,
},
и я хочу получить данные, применив условие к page
свойству, page
это схема, в которой есть свойство url.
схема страницы:
{
title: {
type: String,
required: [true, 'Please add page title'],
unique: true,
trim: true,
maxlength: [50, 'Name cannot be more then 50 characters'],
},
url: {
type: String,
required: [true, 'Add page URL'],
},
createdAt: {
type: Date,
default: Date.now,
},
},
я хочу получить все объявления, соответствующие указанному URL страницы.
мой запрос выглядит так:
if (req.params.pageUrl) {
const ads = await Ads.find({
'page.url': req.params.pageUrl,
});
return res.status(200).json({
success: true,
message: 'Successfully fetched ads for specific page',
count: ads.length,
data: ads,
});
}
url страницы в параметре хорош, но почему-то этот фильтр не работает, я не получил ошибки, но с нулевыми результатами.
я попробовал $match
свойство, но получил некоторую ошибку верхнего уровня.
приветствуется любая помощь по запросу вложенного объекта ref.
Ответ №1:
Вы могли бы использовать aggregate
и $lookup
для этого. Вы можете увидеть более подробную информацию в разделе агрегирование.
Ваш ads_pages
вывод — ваш adspages
. Первый элемент в совокупном массиве $lookup
поможет вам найти все совпадающие условия, которые _id
в adspage равны page
ads и url
adspage
равны вашим req.params.pageUrl
.
Второй элемент в совокупном массиве $match
поможет вам удалить документ, содержащий пустые страницы ads_pages, что означает, что его условие не соответствует вышеуказанным условиям. Вы могли бы использовать это https://jsfiddle.net/cuxvd2pm чтобы проверить.
await AdsModel.aggregate([
{
$lookup: {
// This name must be same as your collection name "in the mongodb"
// In my case, I must use lowercase string, and add more extra "s" in the end
// If you didn't modify extra configuration, I think you should also do it.
from: "adspages",
// you could use as: "page" to replace the original field
as: "ads_pages",
let: { "page_id": "$page"},
pipeline: [{
$match: {
$expr: {
$and: [
{$eq: ["$url", req.params.pageUrl]},
{$eq: ["$_id", "$page_id"]}
]
}
}
}]
}
},
{
$match: {
// when you change your `as field` to page
// you should also change `ads_pages.0` to `page.0`
"ads_pages.0": {
$exists: true
}
}
}
])
Комментарии:
1. Спасибо за ваш ответ, но, похоже, это не работает. Может быть имя схемы Ads
Ads
и схема страницы AdsAdsPage
. может быть, я путаю с именами, которые вы использовали. jsfiddle.net/rdo7ukb52. ваш
let: { page: '$page' }
не такой, как у меня, вы должны использоватьlet: { "page_id": "$page"}
. Затем вы просто меняете имя схемыfrom: {your_schema_name}
, которое изmongoose.model('{here}', AdsPageScheme);
3. я ценю вашу помощь. но по-прежнему нет результатов и ошибок
4. @ArslanAmeer Вы могли бы использовать этот пример кода, чтобы выяснить, как использовать aggregate jsfiddle.net/cuxvd2pm . Убедитесь, что вы заменили URL-адрес подключения на свой и запустите его в своей среде.
5. Используйте
as: "page"
и$match: {"page.0": {$exists: true}}
.