首页 > 解决方案 > 如何通过mongoose中的查询ref对象获取数据

问题描述

我有一个问题,未能找到我正在寻找的东西。我也有这个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 对象的任何帮助。

标签: node.jsmongodbmongoosemean-stackmongoose-schema

解决方案


你可以使用aggregate$lookup做到这一点。您可以在聚合中看到更多详细信息。

ads_pages的输出是你的adspages. 聚合数组中的第一个元素,$lookup将帮助您找到_id在 adspage中等于pageads 且等于您的.urladspagereq.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
            }
        }
    }
])

推荐阅读