通过 Id 查找文档并在 Mongoose 中过滤子数组

Posted

技术标签:

【中文标题】通过 Id 查找文档并在 Mongoose 中过滤子数组【英文标题】:Find a document by Id and filter a subarray in Mongoose 【发布时间】:2021-03-23 04:54:36 【问题描述】:

大家!几天前,我正在网上寻找解决我的问题的方法,经过多次失败的尝试,我决定在这里提出我的第一个问题。

所以,我有一个这样的模型:

const Exercise = new Schema (
    
        description: String,
        duration: Number,
        date: Date
    ,
    
        _id: false
    
);

const User = new Schema(
    username: String,
    log: [
        Exercise
    ]
);

我想找到一个特定的用户并在一个日期范围内过滤他/她的锻炼日志。如果该范围内没有任何练习,我只想将 id、用户名和日志作为空数组返回。所以,我建立了这个查询:

User.aggregate([
        
            $match: 
                _id: userIdInput
            
        ,
        
            $project: 
                _id: 1,
                username: 1,
                log:  
                    $filter:  
                        input: "$log", 
                        as: "log", 
                        cond:  
                            $gte: [ "$$log.date", from ]
                         
                     
                
            
        ])
        .exec()
        .then((log) => 
            res.json(log);
        )
        .catch(err => 
            next(err);
        );
       

但是这个查询总是返回一个空数组。我做错了什么或者有什么提示可以更好地编写这个查询吗?

非常感谢任何帮助。

【问题讨论】:

您的from 数据类型是什么?是字符串、日期还是数字?比较值应该是Date。我试过this,它似乎工作正常。这是您的查询,但使用 ISODate("...") 而不是 from @J.F.嘿,我试过你发送的链接,它确实有效。 from 数据类型是 Date,我在上面使用 toISOString()。无论如何,即使我以duration 为例,它仍然无法正常工作。我乞求认为问题不在于查询,但它可能与 Mongoose 不兼容。 【参考方案1】:

原来问题是当我们在 mongoose 中使用 aggregate() 时,我们必须手动将 id 字符串转换为 ObjectId 类型,因为它不会像 find() 那样自动执行此操作。

资源:Moongoose aggregate $match does not match id's

【讨论】:

以上是关于通过 Id 查找文档并在 Mongoose 中过滤子数组的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose如何过滤填充字段

mongodb/mongoose findMany - 查找 ID 列在数组中的所有文档

Mongoose:根据另一个集合中的值过滤集合

如何在不使用 _id 字段但使用多个属性的情况下在 mongoose 中查找子文档

Mongoose:过滤,如果存在则更新文档,否则创建它

Mongoose:过滤,如果存在则更新文档,否则创建它