Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 更新MongoDB中的嵌套数组对象_Node.js_Mongodb - Fatal编程技术网

Node.js 更新MongoDB中的嵌套数组对象

Node.js 更新MongoDB中的嵌套数组对象,node.js,mongodb,Node.js,Mongodb,我必须在NodeJS应用程序中处理以下类型的对象(使用mongodb驱动程序): 我每2分钟收到一次上述数据。 我想: 如果收到的数据的id尚未出现在MongoDB上,请执行插入 如果接收到的数据中有一个样本对象的日期(t属性)尚未出现,则向该样本对象添加属性(例如,不同传感器的读数) 如果接收到的数据的样本对象的日期(t属性)尚未出现在样本数组中,则添加此新对象 我想用MongoDB服务器可能的少量往返次数来完成上面描述的工作。 我希望已经足够清楚了。 有什么建议吗? 提前谢谢。这是我的建议,

我必须在NodeJS应用程序中处理以下类型的对象(使用mongodb驱动程序):

我每2分钟收到一次上述数据。 我想:

  • 如果收到的数据的id尚未出现在MongoDB上,请执行插入
  • 如果接收到的数据中有一个样本对象的日期(t属性)尚未出现,则向该样本对象添加属性(例如,不同传感器的读数)
  • 如果接收到的数据的样本对象的日期(t属性)尚未出现在样本数组中,则添加此新对象
  • 我想用MongoDB服务器可能的少量往返次数来完成上面描述的工作。 我希望已经足够清楚了。 有什么建议吗?
    提前谢谢。

    这是我的建议,这不是正确的答案。您将需要处理查询部分。下面的查询应该适用于1和3,对于2,您将不得不到处玩

    db.collection.updateOne(
          { "id" : "105-20090412", "samples.t": <Date> },
          { $push: { "samples" : <sample> } },
          { $setOnInsert: { station: <station> } },
          { upsert: true }
       );
    
    db.collection.updateOne(
    {“id”:“105-20090412”,“samples.t”:},
    {$push:{“样本”:},
    {$setOnInsert:{station:}},
    {upsert:true}
    );
    
    参考资料:


    我终于找到了以下解决方案,也许不是最有效的:

      try {
            const db = client.db(dbName);
            const collection = db.collection(collectionName);
    
            // retrive id, station, date  and samplesToAdd as separate objects 
            let {
                id,
                ...dataToInsert
            } = data
    
            //id = new ObjectID(id)
            const queryBy_id = {
                _id: id
            }
    
    
            // first check if doc exists
            let res_query = await collection.findOne(queryBy_id)
    
            // if doc does not exists then insert a new one
            if (!res_query) {
                res_insert = await collection.insertOne({
                    _id: id,
                    ...dataToInsert
                })
                return res_insert;
            } else {
                // retrive samples from initial query
                let current_samples = res_query.samples
    
                // check if sample in dataToInsert yet exists 
                // use getTime to correctly compare dates
                let idx = current_samples.findIndex(x => x.t.getTime() == dataToInsert.samples[0].t.getTime())
    
    
                if (idx >= 0) {
                    // find index of sample to update
                    let current_t = current_samples[idx].t
    
                    // merge data yet stored with new one
                    current_samples.data = {
                        ...current_samples[idx].data,
                        ...dataToInsert.samples[0].data
                    }
    
                    let resUpdateSample = await collection.updateOne({
                        _id: id,
                        'samples.t': current_t
                    }, {
                        $set: {
                            'samples.$.data': current_samples.data
                        }
                    })
                    return resUpdateSample
    
                } else {
                    // add data to samples array
                    let resAddToSamples = await collection.updateOne({
                        _id: id
                    }, {
                        $push: {
                            samples: dataToInsert.samples[0]
                        }
                    })
                    return resAddToSamples
                }
    
            }
    
        } catch (err) {
            logger.error(err);
        }
    
    我怎样才能改进它?
    谢谢。

    谢谢,但它不起作用,我认为推动部分有问题。
      try {
            const db = client.db(dbName);
            const collection = db.collection(collectionName);
    
            // retrive id, station, date  and samplesToAdd as separate objects 
            let {
                id,
                ...dataToInsert
            } = data
    
            //id = new ObjectID(id)
            const queryBy_id = {
                _id: id
            }
    
    
            // first check if doc exists
            let res_query = await collection.findOne(queryBy_id)
    
            // if doc does not exists then insert a new one
            if (!res_query) {
                res_insert = await collection.insertOne({
                    _id: id,
                    ...dataToInsert
                })
                return res_insert;
            } else {
                // retrive samples from initial query
                let current_samples = res_query.samples
    
                // check if sample in dataToInsert yet exists 
                // use getTime to correctly compare dates
                let idx = current_samples.findIndex(x => x.t.getTime() == dataToInsert.samples[0].t.getTime())
    
    
                if (idx >= 0) {
                    // find index of sample to update
                    let current_t = current_samples[idx].t
    
                    // merge data yet stored with new one
                    current_samples.data = {
                        ...current_samples[idx].data,
                        ...dataToInsert.samples[0].data
                    }
    
                    let resUpdateSample = await collection.updateOne({
                        _id: id,
                        'samples.t': current_t
                    }, {
                        $set: {
                            'samples.$.data': current_samples.data
                        }
                    })
                    return resUpdateSample
    
                } else {
                    // add data to samples array
                    let resAddToSamples = await collection.updateOne({
                        _id: id
                    }, {
                        $push: {
                            samples: dataToInsert.samples[0]
                        }
                    })
                    return resAddToSamples
                }
    
            }
    
        } catch (err) {
            logger.error(err);
        }