Mongodb多层嵌套数组如何精确查询(内容处为格式化的json截图,评论里面是json的内容)?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mongodb多层嵌套数组如何精确查询(内容处为格式化的json截图,评论里面是json的内容)?相关的知识,希望对你有一定的参考价值。

json格式就贴图如上了,现在我想查出所有hobbyName是电影的人员的信息(返回的应该是个包含name,sex,hobbies的集合);想通过下个语句查出所有hobbyName是音乐的人名的集合现在我的问题是如果嵌套多层数组的话db.getCollection('person').find("excelID":"10001","sheetArrays.studentInfos.hobbies.hobbyName":"电影","sheetArrays.studentInfos.$":1)这条查询只能过滤掉第一层数组,也就是说我智能知道hobbyName为电影的人员来自于一班,但我不知道具体是哪位同学,希望有人能帮我答疑解惑,感激不尽!

参考技术A 感觉你设计的数据结构太复杂,内嵌文档太多层了,为什么不一个学生一条记录呢,这样设计部是更简洁吗,查询统计什么的都很简单,你现在的文档一次查询是得不到你想要的结构的,只能用聚合看能不能实现。本回答被提问者和网友采纳

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

【中文标题】如何在 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多层嵌套数组如何精确查询(内容处为格式化的json截图,评论里面是json的内容)?的主要内容,如果未能解决你的问题,请参考以下文章

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

MongoDB:如何查询嵌套数组?

如何使用 findOne 查询 mongodb 并排除数组中的一些嵌套字段

mongodb 查询求助,嵌套数组里面查东西

MongoDB:如何使用查找查询填充嵌套对象?

在 MongoDb 中查询嵌套数组