【问题标题】:Mongoose NodeJS Express - Edit a specific sub document fieldMongoose NodeJS Express - 编辑特定的子文档字段
【发布时间】:2021-02-16 22:25:54
【问题描述】:

我的 Node 服务器中设计了以下架构


架构

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const dataSchema = new Schema({
    time: Date,
    value: String
});

const nodeSchema = new Schema({
    name: String,
    description: String,
    number: Number,
    status: String,
    lastSeen: Date,
    data: [dataSchema]
});

const siteSchema = new Schema({
    code: String,
    name: String,
    description: String,
    totalNodes: Number,
    nodes: [nodeSchema]
});

const Site = mongoose.model('site',siteSchema);
module.exports = Site;

它们基本上是这样的。你可以看到有两个节点有一些演示数据。

示例

 {
        "_id": "5fa169473a394829bc485069",
        "code": "xfx3090",
        "name": "Name of this site",
        "description": "Some description",
        "totalNodes": 2,
        "__v": 0,
        "nodes": [
            {
                "_id": "5fa1af361e085b516066d7e2",
                "name": "device name",
                "description": "device description",
                "number": 1,
                "status": "Offline",
                "lastSeen": "2020-11-03T19:27:50.062Z",
                "data": [
                    {
                        "Date": "2019-01-01T00:00:00.000Z",
                        "value": "12"
                    },
                    {
                        "Date": "2019-01-01T00:00:00.000Z",
                        "Value": "146"
                    }
                ]
            },
            {
                "_id": "5fa1b10f4f24051520f85a58",
                "name": "device name",
                "description": "device description",
                "number": 2,
                "status": "Offline",
                "lastSeen": "2020-11-03T19:35:43.409Z",
                "data": [
                    {
                        "Date": "2019-01-01T00:00:00.000Z",
                        "Value": "555"
                    }
                ]
            }
        ]
    }
]

我的问题是如何更新节点的特定字段,特别是如何更新最后看到的或状态。值得一提的是,发出请求的客户端只能访问站点代码和节点号。站点和节点的对象 ID 将是未知的。

到目前为止,这就是我所拥有的,但由于某种原因它只创建了一个新的对象 ID。

任何建议将不胜感激

 updateNode: async (req,res,next) => {
        const {siteCode} = req.params;
        const { nodeNumber } = req.params;
        const status = req.body.status;

        const nodeStatus = await Site.findOneAndUpdate({'code': siteCode, 'nodes.number':nodeNumber}, { '$set': {'nodes.$.status': {'status':status}}});

        res.status(200).json({message: 'success'});
    }

【问题讨论】:

  • 欢迎来到 Stackoverflow。提出问题时,请尝试显示您提出问题之前收到的输出,以便我们获得更多调试信息。
  • Site.findOneAndUpdate({'code': siteCode, 'nodes.number':nodeNumber}, { '$set': {'nodes.$.status': {'status':status}}}) 这不行吗?
  • 它执行但没有给出我想要的结果。本质上,它在数据数组上创建了另一个对象 ID。我希望它只使用站点代码和节点号来更改在线状态或上次看到的状态
  • 你能在你尝试之前和之后给你照片吗?你想要什么真实的结果?
  • 我不明白creates another Object Id on the data array

标签: node.js json mongodb express mongoose


【解决方案1】:

您需要这样做。 我已经预定义了._ids。 如果需要,您可以动态执行此操作。如果您使用的是快递,您可以只使用查询。示例req.query.documentID。访问它的 URL 是localhost:p/?documentID=5fa169473a394829bc485069&nodeID=5fa1af361e085b516066d7e2

localhost 中的p 用于端口

    await Site
        .findOne({ 
            "_id": "5fa169473a394829bc485069",
            "nodes._id": "5fa1af361e085b516066d7e2" 
        })
        .update({ "lastSeen": Date })
        .then(doc => res.json(doc))
        .catch(e => console.log(e))

基本上找到一个id为5fa169473a394829bc485069的文档 然后是node_id5fa1af361e085b516066d7e2 然后将update() 方法和{ "lastSeen": Date } 参数传递给Date。 就是这样!

编辑
您必须通过这样做来创建一个 VALID MongoDB 对象

app.get("/new", async (req, res) => {
    let Site = new model({
        code: "String",
        name: "String",
        description: "String",
        totalNodes: 2,
        nodes: [
            {
                _id: new mongoose.Types.ObjectId,
                name: "String",
                description: "String",
                number: 1,
                status: "offline",
                lastSeen: Date.now(),
                data: [{ "someData": "someData" }]
            },
            {
                _id: new mongoose.Types.ObjectId,
                name: "String",
                description: "String",
                number: 2,
                status: "offline",
                lastSeen: Date.now(),
                data: [{ "someData": "someData" }]
            }
        ]
    });

    await Site
        .save()
        .then(doc => {
            console.log(doc);
            res.json(doc);
        })
        .catch(e => console.error(e));
});

一切都加载了虚拟数据。然后你像这样更新数据。

app.get("/", async (req, res) => {
    await model
        .findOne({ "code": "String" })
        .update({
            "nodes.0.status": "online"
        })
        .then(doc => {
            console.log(doc);
            res.json(doc);
        })
        .catch(e => console.error(e));
})

基本上你可以像nodes.0 这样访问索引位置 0(这意味着第一个帖子)处的对象,然后该对象的状态将分别为nodes.0.status。然后你只需保存对象就可以了!

【讨论】:

  • 是的,这应该可以,但问题是发出请求的客户端只能访问节点号。因此,我希望有一种方法可以在没有节点 ID 的情况下做到这一点?
  • 幸运的是,你可以!再看看我的回答。我更新了它。我花了一些时间来做这件事,但这是值得的。
猜你喜欢
  • 2015-03-27
  • 2021-02-16
  • 1970-01-01
  • 2016-06-14
  • 1970-01-01
  • 2014-11-15
  • 2015-06-02
  • 1970-01-01
  • 2019-02-26
相关资源
最近更新 更多