【问题标题】:Mongodb mongoose - How to add a document to an array if not present by a fieldMongodb mongoose - 如果字段不存在,如何将文档添加到数组中
【发布时间】:2020-02-23 18:13:29
【问题描述】:

这样的文件

{
    "_id" : ObjectId("5db65eb2a2f3a61fe88e162a"), 
    "devicesCxt" : [
        {
            "deviceId" : "1232", 
            "userAgent" : "PostmanRuntime/7.19.0", 
            "online" : false, 
            "_id" : ObjectId("5db65eb2a2f3a61fe88e162c"), 
            "loginAt" : ISODate("2019-10-28T03:21:22.178+0000")
        }
    ], 
}

我想添加这个

{
    "deviceId" : "1233", 
    "userAgent" : "PostmanRuntime/7.19.0", 
    "online" : false, 
    "_id" : ObjectId("5db65eb2a2f3a61fe88e162b"), 
    "loginAt" : ISODate("2019-10-28T03:21:22.178+0000")
}

我想要这样的东西

{
    "_id" : ObjectId("5db65eb2a2f3a61fe88e162a"), 
    "devicesCxt" : [
        {
            "deviceId" : "1232", 
            "userAgent" : "PostmanRuntime/7.19.0", 
            "online" : false, 
            "_id" : ObjectId("5db65eb2a2f3a61fe88e162c"), 
            "loginAt" : ISODate("2019-10-28T03:21:22.178+0000")
        },
        {
            "deviceId" : "1233", 
            "userAgent" : "PostmanRuntime/7.19.0", 
            "online" : false, 
            "_id" : ObjectId("5db65eb2a2f3a61fe88e162b"), 
            "loginAt" : ISODate("2019-10-28T03:21:22.178+0000")
        }
    ],
}

如果deviceId: 1232不允许,否则deviceId: 1233可以成功。

deviceId 不能有相同的对象

deviceId 在数组中应保持唯一。

我该怎么做?

【问题讨论】:

  • 你试过这个例子了吗stackoverflow.com/questions/33049707/…
  • 谢谢 Jayakumar Thangavel,这不是我想要的,我希望 deviceId 不要重复
  • 您可以尝试在 deviceId 字段上创建unique index
  • 我正在尝试寻找一种方法来确定添加时是否存在 deviceId
  • @Amorous 如果我理解正确,如果它不包含具有相同 deviceId.. 的对象,您想更新/添加新传入对象到 devicesCxt 数组。对吗?

标签: javascript node.js mongodb mongoose


【解决方案1】:

当传入对象的 deviceId 已经存在时,可以有条件更新查询以防止将文档添加到 devicesCxt 数组字段。 $push

Mongo 查询:

const incomingDoc = {
  deviceId: "1233",
  userAgent: "PostmanRuntime/7.19.0",
  online: false,
  _id: ObjectId("5db65eb2a2f3a61fe88e162b"),
  loginAt: ISODate("2019-10-28T03:21:22.178+0000")
};

db.collection.update(
  {
    _id: idToFilterIfAny,
    "devicesCxt.deviceId": { $ne: incomingDoc.deviceId }
  },
  { $push: { devicesCxt: incomingDoc } }
);

【讨论】:

  • @Amorous 看看这是不是你需要的。基本思想是过滤要更新的字段,当deviceId 不存在时添加文档。
  • 太好了,这正是我需要的,非常感谢@ambianBeing,我不想改变我的架构,这对我来说是最好的方式。再次感谢
  • 请问,如果有执行修改,其他情况会添加。请问怎么办?
  • @Amorous 建议提出一个新的自包含问题,并添加所有新案例,这有助于在 SO 获得更好的可见性和其他人的帮助,并指向它的链接,我会检查出来吧。
【解决方案2】:

更新

您的架构可能是这样的:

const mySchema = new Schema({
  deviceCtx: [{
      deviceId : { type: String, unique: true},
      userAgent : { type: String, },
      online : { type: Boolean, },
      loginAt : { type: Date, },
    }]
});

在数组中添加新项目:

const mySchema = await mySchema.find({ _id: "5db65eb2a2f3a61fe88e162a" });

const newDeviceId = req.body.deviceId;
mySchema.devicesCxt.push({
  deviceId : newDeviceId,
  userAgent : "PostmanRuntime/7.19.0",
  online : false,
  loginAt : new Date()
});

await mySchema.save();

【讨论】:

  • @Amorous 你想让你的deviceId 自动递增吗?
  • 那么上面的代码应该可以工作了。因为,deviceId 设置为unique
  • 让我试试,再次感谢@Dijkstra ,不同的文档允许同一个deviceId存在,但同一个数组中只有一个
【解决方案3】:

使用这个。

let deviceid = {
    "deviceId" : "1233", 
    "userAgent" : "PostmanRuntime/7.19.0", 
    "online" : false, 
    "_id" : ObjectId("5db65eb2a2f3a61fe88e162b"), 
    "loginAt" : ISODate("2019-10-28T03:21:22.178+0000")
}
myModel.update(

    { $push: { devicesCxt: deviceid } },
);

但如果你想 mongo 将 _id 添加到你的数组中,你需要在你的架构中定义它

【讨论】:

猜你喜欢
  • 2019-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
  • 2016-10-16
  • 1970-01-01
  • 2023-02-14
相关资源
最近更新 更多