【问题标题】:How to get data by query ref object in mongoose如何通过mongoose中的查询ref对象获取数据
【发布时间】:2021-04-04 22:01:49
【问题描述】:

我遇到了一个问题,未能找到我正在寻找的内容。 我也有这个 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,
    },
},

我想获取与提供的页面网址匹配的所有广告。

我的查询如下:

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,
    });
}

参数中的页面网址很好,但不知何故,这个过滤器不起作用,我没有错误但结果为零。 我尝试了$match 属性,但出现了一些上层错误。

非常感谢有关查询嵌套 ref 对象的任何帮助。

【问题讨论】:

    标签: node.js mongodb mongoose mean-stack mongoose-schema


    【解决方案1】:

    您可以使用aggregate$lookup 来执行此操作。您可以在aggregation 中查看更多详细信息。

    您的ads_pages 输出是您的adspages。聚合数组中的第一个元素 $lookup 将帮助您找到所有匹配条件,即 adspage 中的 _id 等于广告中的 pageadspage 中的 url 等于您的 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
                }
            }
        }
    ])
    

    【讨论】:

    • 感谢您的回复,但这似乎不起作用。 5 月广告架构名称为 Ads,广告页面架构为 AdsPage。可能我对您使用的名称感到困惑。 jsfiddle.net/rdo7ukb5
    • 你的let: { page: '$page' }和我的不一样,你应该用let: { "page_id": "$page"}。然后,您只需更改架构名称 from: {your_schema_name},它来自 mongoose.model('{here}', AdsPageScheme);
    • 感谢您的帮助。但仍然没有结果,也没有错误
    • @ArslanAmeer 您可以使用此示例代码来了解如何使用聚合 jsfiddle.net/cuxvd2pm。确保将连接 url 替换为你的,并在你的环境中运行。
    • 使用as: "page"$match: {"page.0": {$exists: true}}
    猜你喜欢
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    相关资源
    最近更新 更多