Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.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
Mongodb 修改子文档/深度嵌套文档时,Parent.save()不起作用_Mongodb_Mongoose_Mongodb Query - Fatal编程技术网

Mongodb 修改子文档/深度嵌套文档时,Parent.save()不起作用

Mongodb 修改子文档/深度嵌套文档时,Parent.save()不起作用,mongodb,mongoose,mongodb-query,Mongodb,Mongoose,Mongodb Query,我从整个收藏中发现我的文档如下: const account = await Account.findOne({ "buildings.gateways.devices.verificationCode": code }) const buildings = account.buildings const gateways = buildings[0].gateways; const devices = gateways[0].devices; const

我从整个收藏中发现我的文档如下:

    const account = await Account.findOne({ "buildings.gateways.devices.verificationCode": code })
    const buildings = account.buildings
    const gateways = buildings[0].gateways;
    const devices = gateways[0].devices;
    const device = _.filter(devices, d => d.verificationCode === code);
现在我想更改patientLastName的一个属性,然后保存整个文档。我正在做下面的事情

device.patientLastName = lastName;
const updated = await account.save();
这根本改变不了什么。我尝试过很多解决方案,但都不奏效。 不确定我是否可以像那样保存父文档

我很少有其他调用使用相同的代码,但唯一的变化是,这是在我的post调用中,而工作调用是在put调用中

我的模式:

const accountSchema = new mongoose.Schema({
  email: { type: String, unique: true, required: true },
  password: { type: String, required: true },
  userName: { type: String, unique: true, required: true },
  companyName: { type: String, required: true },
  apiKey: { type: String, unique: true, required: true },
  apiCallCount: { type: Number, default: 0 },
  solutionType: String,
  parentCompany: String,
  buildings:
    [
      new mongoose.Schema({
        buildingName: String,
        address: String,
        suite: String,
        floor: String,
        timeZone: String,
        gateways:
        [
          new mongoose.Schema({
            gatewayName: String,
            gatewayKey: { type: String, sparse: true },
            suite: String,
            devices: [
              new mongoose.Schema({
                serialNumber: { type: String, sparse: true },
                area: String,
                connectionStatus: Number,
                gatewayKey: String,
                applicationNumber: Number,
                firmwareVersion: String,
                needsAttention: Boolean,
                verificationCode: String,
                patientRiskStatus: String,
                patientFirstName: String,
                patientLastName: String
              }, { timestamps: true })
            ]
          }, { timestamps: true })
        ]
      }, { timestamps: true })
    ]
}, { timestamps: true });
更新: 我正在尝试: 它给我错误信息- 消息:将循环结构转换为JSON

  const updated = account.update(
    {
        "_id" : ObjectId(accountId),
        "buildings.gateways.devices.verificationCode": code
    }, 
    {
        "$set": { 
            "buildings.$.gateways.0.devices.0.patientFirstName": "name1", 
            "buildings.$.gateways.0.devices.0.patientLastName": "name2", 
        }
    }
)
谢谢你的帮助。谢谢

更新-

完成电话咨询,供您参考

    // Register User
    loginRouter.post('/register', async (req, res, next) => {
        try {

            var { email, userName, password, firstName, lastName, role, deviceIds, code } = req.body;
            console.log(req.body)
            // checking if email or username already exist before registering. 
            const verifyEmail = await User.find({
                $or: [
                    { 'email': email },
                    { 'userName': userName },
                ]
            })
            if (verifyEmail.length > 0) {
                throw new BadRequestError('DuplicateEmailOrUserName', {
                    message: 'Email or Username already exists'
                });
            }
            // finding accountId for verification code first
            const account = await Account.findOne({ "buildings.gateways.devices.verificationCode": code })
            //console.log(account)
            if (account.length === 0) {
                console.log("Invalid registration code")
                throw new BadRequestError('InvalidVerificationCode', {
                    message: 'Invalid registration code'
                });
            }
            var accountId = account ? account._id : null

            const buildings = account.buildings
            const gateways = buildings[0].gateways;
            const devices = gateways[0].devices;

            //console.log("devices", devices)

            // finding deviceId to insert for user from that account
            const device = _.filter(devices, d => d.verificationCode === code);

           // console.log("device", device)
            if (!deviceIds) {
                deviceIds = device.map(item => item._id)
            //    console.log("deviceIds", deviceIds)
            }
            const hashedPassword = await hasher.hashPassword(password);
            const newUser = new User({
                accountId: accountId ? accountId : undefined,
                userName: userName,
                password: hashedPassword,
                email: email,
                firstName: firstName,
                lastName: lastName,
                role: role,
                refreshToken: uuidv4(),
                refreshTokenExpiryDate: moment().add(process.env.REFRESH_TOKEN_EXPIRY_IN_DAYS, 'days'),
                deviceIds: deviceIds ? deviceIds : [],
                isActive: true,
            });
            const newlySavedUser = await newUser.save();

            const {
                refreshToken,
                refreshTokenExpiryDate,
                password: pwd,
                ...userWithoutSensitiveInfo
            } = newlySavedUser.toObject();


**// solutions by @SuleymanSah** <----


try {
        let result = await Account.findByIdAndUpdate(
         accountId,
          {
            $set: {
              "buildings.$[building].gateways.$[gateway].devices.$[device].patientFirstName": "userName"
            }
          },
          {
            arrayFilters: [

              { "building._id": ObjectId("5d254bb179584ebcbb68b712") },
              { "gateway._id": ObjectId("5d254b64ba574040d9632ada") },
              { "device.verificationCode": "4144" }
            ],
            new: true
          }
        );

        if (!result) return res.status(404);
    console.log(result)
        //res.send(result);
      } catch (err) {
        console.log(err);
        res.status(500).send("Something went wrong");
      }

        res.json(newlySavedUser);
        next();
    } catch (err) {
        next(err);
    }
});
如果你需要更多信息,请告诉我。谢谢

您可以使用

注意,我们还需要buildingId和gatewayId以使其动态工作

router.put("/account/:accountId/:buildingId/:gatewayId", async (req, res) => {
  const { patientFirstName, verificationCode } = req.body;
  try {
    let result = await Account.findByIdAndUpdate(
      req.params.accountId,
      {
        $set: {
          "buildings.$[building].gateways.$[gateway].devices.$[device].patientFirstName": patientFirstName
        }
      },
      {
        arrayFilters: [
          { "building._id": req.params.buildingId },
          { "gateway._id": req.params.gatewayId },
          { "device.verificationCode": verificationCode }
        ],
        new: true
      }
    );

    if (!result) return res.status(404);

    res.send(result);
  } catch (err) {
    console.log(err);
    res.status(500).send("Something went wrong");
  }
});
试验

让我们来看看这个文档:

{
    "_id" : ObjectId("5e0da052b4b3fe5188602e11"),
    "apiCallCount" : 1,
    "email" : "abc@def.net",
    "password" : "123123",
    "userName" : "username",
    "companyName" : "companyName",
    "apiKey" : "apiKey",
    "solutionType" : "solutionType",
    "parentCompany" : "parentCompany",
    "buildings" : [
        {
            "_id" : ObjectId("5e0da052b4b3fe5188602e12"),
            "buildingName" : "buildingName 1",
            "address" : "address",
            "suite" : "suite",
            "floor" : "floor",
            "timeZone" : "String",
            "gateways" : [
                {
                    "_id" : ObjectId("5e0da052b4b3fe5188602e13"),
                    "gatewayName" : "gatewayName 1",
                    "gatewayKey" : "gatewayKey",
                    "suite" : "suite",
                    "devices" : [
                        {
                            "_id" : ObjectId("5e0da052b4b3fe5188602e15"),
                            "serialNumber" : "serialNumber 1",
                            "area" : "area",
                            "connectionStatus" : 0,
                            "gatewayKey" : "gatewayKey",
                            "applicationNumber" : 11,
                            "firmwareVersion" : "firmwareVersion",
                            "needsAttention" : true,
                            "verificationCode" : "123456",
                            "patientRiskStatus" : "patientRiskStatus",
                            "patientFirstName" : "patientFirstName",
                            "patientLastName" : "patientLastName",
                            "createdAt" : ISODate("2020-01-02T10:48:34.287+03:00"),
                            "updatedAt" : ISODate("2020-01-02T10:48:34.287+03:00")
                        },
                        {
                            "_id" : ObjectId("5e0da052b4b3fe5188602e14"),
                            "serialNumber" : "serialNumber 2",
                            "area" : "area",
                            "connectionStatus" : 0,
                            "gatewayKey" : "gatewayKey",
                            "applicationNumber" : 22,
                            "firmwareVersion" : "firmwareVersion",
                            "needsAttention" : true,
                            "verificationCode" : "987654",
                            "patientRiskStatus" : "patientRiskStatus",
                            "patientFirstName" : "patientFirstName",
                            "patientLastName" : "patientLastName",
                            "createdAt" : ISODate("2020-01-02T10:48:34.288+03:00"),
                            "updatedAt" : ISODate("2020-01-02T10:48:34.288+03:00")
                        }
                    ],
                    "createdAt" : ISODate("2020-01-02T10:48:34.288+03:00"),
                    "updatedAt" : ISODate("2020-01-02T10:48:34.288+03:00")
                }
            ],
            "createdAt" : ISODate("2020-01-02T10:48:34.288+03:00"),
            "updatedAt" : ISODate("2020-01-02T10:48:34.288+03:00")
        }
    ],
    "createdAt" : ISODate("2020-01-02T10:48:34.289+03:00"),
    "updatedAt" : ISODate("2020-01-02T10:48:34.289+03:00"),
    "__v" : 0
}
要使用验证代码123456更新设备patientFirstName,我们需要向url发送PUT请求http://..../account/5e0da052b4b3fe5188602e11/5e0da052b4b3fe5188602e12/5e0da052b4b3fe5188602e13

5e0da052b4b3fe5188602e11是帐户ID

5e0da052b4b3fe5188602e12是buildingId

5e0da052b4b3fe5188602e13是网关ID

请求机构:

{
    "verificationCode": "123456",
    "patientFirstName": "UPDATED!!!"
}
结果如下:

{
    "apiCallCount": 1,
    "_id": "5e0da052b4b3fe5188602e11",
    "email": "abc@def.net",
    "password": "123123",
    "userName": "username",
    "companyName": "companyName",
    "apiKey": "apiKey",
    "solutionType": "solutionType",
    "parentCompany": "parentCompany",
    "buildings": [
        {
            "gateways": [
                {
                    "devices": [
                        {
                            "_id": "5e0da052b4b3fe5188602e15",
                            "serialNumber": "serialNumber 1",
                            "area": "area",
                            "connectionStatus": 0,
                            "gatewayKey": "gatewayKey",
                            "applicationNumber": 11,
                            "firmwareVersion": "firmwareVersion",
                            "needsAttention": true,
                            "verificationCode": "123456",
                            "patientRiskStatus": "patientRiskStatus",
                            "patientFirstName": "UPDATED!!!",
                            "patientLastName": "patientLastName",
                            "createdAt": "2020-01-02T07:48:34.287Z",
                            "updatedAt": "2020-01-02T07:48:34.287Z"
                        },
                        {
                            "_id": "5e0da052b4b3fe5188602e14",
                            "serialNumber": "serialNumber 2",
                            "area": "area",
                            "connectionStatus": 0,
                            "gatewayKey": "gatewayKey",
                            "applicationNumber": 22,
                            "firmwareVersion": "firmwareVersion",
                            "needsAttention": true,
                            "verificationCode": "987654",
                            "patientRiskStatus": "patientRiskStatus",
                            "patientFirstName": "patientFirstName",
                            "patientLastName": "patientLastName",
                            "createdAt": "2020-01-02T07:48:34.288Z",
                            "updatedAt": "2020-01-02T07:48:34.288Z"
                        }
                    ],
                    "_id": "5e0da052b4b3fe5188602e13",
                    "gatewayName": "gatewayName 1",
                    "gatewayKey": "gatewayKey",
                    "suite": "suite",
                    "createdAt": "2020-01-02T07:48:34.288Z",
                    "updatedAt": "2020-01-02T07:48:34.288Z"
                }
            ],
            "_id": "5e0da052b4b3fe5188602e12",
            "buildingName": "buildingName 1",
            "address": "address",
            "suite": "suite",
            "floor": "floor",
            "timeZone": "String",
            "createdAt": "2020-01-02T07:48:34.288Z",
            "updatedAt": "2020-01-02T07:48:34.288Z"
        }
    ],
    "createdAt": "2020-01-02T07:48:34.289Z",
    "updatedAt": "2020-01-02T09:10:25.200Z",
    "__v": 0
}
如果您始终希望在第一个网关的第一个建筑中进行更新,您可以使用以下方法:

router.put("/account/:accountId", async (req, res) => {
  const { patientFirstName, verificationCode } = req.body;
  try {
    let result = await Account.findByIdAndUpdate(
      req.params.accountId,
      {
        $set: {
          "buildings.0.gateways.0.devices.$[device].patientFirstName": patientFirstName
        }
      },
      {
        arrayFilters: [{ "device.verificationCode": verificationCode }],
        new: true
      }
    );

    if (!result) return res.status(404);

    res.send(result);
  } catch (err) {
    console.log(err);
    res.status(500).send("Something went wrong");
  }
});

现在,您只需在url中发送accountId,如下所示:http://../account/5e0da052b4b3fe5188602e11

您能否在jsoneditor online上共享输入数据和帐户模式?我不确定您对jsoneditor online的期望是什么?和帐户的模式几乎在讨论中提到。请检查我是如何通过帐户、建筑物、网关和设备进行迭代的。然后我根据代码过滤设备,并希望更新嵌套文档。你检查了我的答案吗?我刚刚看到了答案。我刚刚醒来。我会尽快试试这个。非常感谢你的努力。非常感谢,非常感谢。按原样编写的代码工作得非常完美。现在我的困难是如何获得buildingId,gatewayId?我可以获得accountId。但不确定如何挖掘并获取特定设备的建筑物和网关id?此呼叫用于注册,因此我没有任何id进入参数。我根据我在请求中获得的不同参数获取帐户Id。@newdeveloper您的新问题完全是另一个问题。你能再问一个新问题吗?混合问题不是一个好主意。请检查我的新问题-当你有机会的时候,你能看看新问题吗?谢谢链接粘贴在上述注释中。