Как получить данные по объекту ref запроса в mongoose

#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 и схема страницы Ads AdsPage . может быть, я путаю с именами, которые вы использовали. jsfiddle.net/rdo7ukb5

2. ваш 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}} .