如何通过mongoose中的查询ref对象获取数据

Posted

技术标签:

【中文标题】如何通过mongoose中的查询ref对象获取数据【英文标题】:How to get data by query ref object in mongoose 【发布时间】: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 对象的任何帮助。

【问题讨论】:

【参考方案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

以上是关于如何通过mongoose中的查询ref对象获取数据的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 中的关联查询MongoDB : aggregate/lookup 对比 Mongoose : ref / populate

Mongoose.js:强制总是填充

如何使用 mongoose 从 refs 获取数组

如何在猫鼬中将对象字段作为数组获取?

在 Mongoose 中使用“Ref”获取 mongo 数据时出现问题

有没有办法通过在 Mongoose 中查询来更新文档数组中的对象?