如何在 MongoDB 中推入具有精确键值的对象嵌套数组?

Posted

技术标签:

【中文标题】如何在 MongoDB 中推入具有精确键值的对象嵌套数组?【英文标题】:How to push inside nested array of object that have a precise value of a key in MongoDB? 【发布时间】:2022-01-11 04:27:30 【问题描述】:

我有一个关于我无法解决的问题的问题。我尝试在我的猫鼬集合中更新推送通过 Query 传递的字符串。 我的收藏是这样的:

    
        "_id": 
            "$oid": "6199288597e42bf84d017f9e"
        ,
        "name": "Lisa",
        "surname": "Bianchi",
        "ID_school": "afbH598U3",
        "classes": [
            
                "class": "5A",
                "activities": 
                    "in_progress": [],
                    "finisched": []
                ,
                "_id": 
                    "$oid": "6199288597e42bf84d017f9f"
                
            ,
            
                "class": "1A",
                "activities": 
                    "in_progress": [],
                    "finisched": []
                ,
                "_id": 
                    "$oid": "6199288597e42bf84d017fa0"
                
            
        ],
        "email": "insegnante@a.com",
        "__v": 0
    

我尝试在 in_progress 数组中推送一个匹配的字符串,例如,使用这种方式与 class:"5A" 匹配:

    import db from "../models/index.js";
    
    const Teacher = db.teacher
    
    const updateActivity = (req, res) => 
        const query =  _id: req.query.id;
        const update =  $push:'classes.$[group].activities.in_progress': req.query.data  ;
        const options = arrayFilters:  'group.class': req.query.class ;
    
        Teacher.findOneAndUpdate(query, update, options).exec((err, data) => 
            if (err) 
                res.status(400).send( message: err );
                return;
             else 
                res.status(200).send(data);
            
        )
    
    
    const API = 
        updateActivity
    
    
    export default API

查询工作正常,但没有推送任何内容。我测试了在 Query 字段中传递的 Whit Insomnia

    id = 6199288597e42bf84d017f9e;
    class:'5A';
    data:"pushed"

有什么建议吗?谢谢!

【问题讨论】:

【参考方案1】:

有两种方法:

选项 1:arrayFilters - 更灵活Docu

您正在使用的选项。 您有语法错误 - arrayFilters 应该是一个文档数组。

const updateActivity = (req, res) => 
  const query =  _id: req.query.id ;
  const update = 
    $push: 'classes.$[group].activities.in_progress': req.query.data 
  ;

  // This MUST be an array of filter documents!
  const options =  arrayFilters: [ 'group.class': req.query.class ] ;
    
  Teacher
    .findOneAndUpdate(query, update, options)
    .exec((err, data) => 
      if (err) 
        res.status(400).send( message: err );
        return;
       else 
        res.status(200).send(data);
      
    );


选项 2:通过查询(@Saurabh Mistry 回答)

为了完整性重复他的回答

通过指定针对结果文档中数组中特定元素的查询。

const updateActivity = (req, res) => 
  const query = 
    _id: req.query.id,
    'classes.class': req.query.data,
  ;
  const update = 
    $push: 'classes.$.activities.in_progress': req.query.data 
  ;

  Teacher
    .findOneAndUpdate(query, update, options)
    .exec((err, data) => 
      if (err) 
        res.status(400).send( message: err );
        return;
       else 
        res.status(200).send(data);
      
    );


【讨论】:

谢谢!这两个解决方案工作正常(200 OK)但不要推入 in_progress 数组。我不知道为什么。 已解决,您的查询很好,我的 Mongoose 模型有问题。谢谢!【参考方案2】:

通过在查询中传递classes.class 尝试这种方式,并将推送更改为$push:'classes.$.activities.in_progress': req.query.data

 const updateActivity = (req, res) => 
    const query =  _id: req.query.id ,'classes.class': req.query.class;
    const update =  $push:'classes.$.activities.in_progress': req.query.data  ;

    Teacher.updateOne(query,update).exec((err, data) => 
        if (err) 
            res.status(400).send( message: err );
            return;
         else 
            res.status(200).send(data);
        
    )

【讨论】:

此解决方案尚未推入数组 in_progress,查询工作正常(200 OK)。 已解决,您的查询很好,我的 Mongoose 模型有问题。谢谢!

以上是关于如何在 MongoDB 中推入具有精确键值的对象嵌套数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Django中查询具有特定数量的外键关系并且在这些外键值中具有特定值的对象?

Mongodb聚合:从键值对象返回不同值的计数

删除嵌套数组中具有键值的对象

在 JavaScript 中获取具有键值的对象数据

在具有显式键值的对象列表中查找元素

检查对象数组中是不是存在具有特定键值的对象