有没有办法唯一存储ObjectId数组?

问题描述 投票:0回答:1

我正在创建一个消息传递模式,并希望确保(聚合的)参与者被唯一存储(即线程中的两个参与者,存储为对象 ID 不能重复)。

理想的方法是以特定顺序存储它们,还是有更好的方法通过 MongoDB/Mongoose 实现这一点?

mongodb mongoose mongoose-schema
1个回答
0
投票

这里有两种方法:

1.对配对执行一致的顺序

一个简单的解决方案是对参与者 ID 强制排序,以便它们始终以一致的顺序存储(例如,始终存储

[smaller ID, larger ID]
)。这样,
{ participantA: ObjectId1, participantB: ObjectId2 }
始终存储为
[{ smaller ID }, { larger ID }]
。然后,您可以在两个参与者字段上创建唯一的复合索引:

javascript 复制代码 db.messages.createIndex({ 参与者A: 1, 参与者B: 1 }, { unique: true }); 要在 Mongoose 中执行此操作:

const messageSchema = new Schema({
  participantA: { type: Schema.Types.ObjectId, required: true },
  participantB: { type: Schema.Types.ObjectId, required: true }
});

// Ensure unique pairs in a consistent order
messageSchema.index({ participantA: 1, participantB: 1 }, { unique: true });

const Message = mongoose.model("Message", messageSchema);

此方法假设您在应用程序逻辑中始终对

participantA
participantB
进行排序(例如,始终首先存储较小的 ID)。

2.使用聚合数组进行排序

或者,您可以将参与者存储为 ObjectId 数组,进行排序以确保顺序一致,然后在此数组上创建唯一索引:

const messageSchema = new Schema({
  participants: {
    type: [Schema.Types.ObjectId],
    required: true,
    validate: {
      validator: (arr) => arr.length === 2,
      message: "Participants array must contain exactly two IDs."
    }
  }
});

// Create a unique index on the array
messageSchema.index({ participants: 1 }, { unique: true });

const Message = mongoose.model("Message", messageSchema);

在此方法中:

  • 确保数组始终包含按排序顺序排列的参与者(保存前
    participants.sort()
    )。
  • 在参与者数组上创建唯一索引。这样,
    [ObjectId1, ObjectId2]
    将被视为与
    [ObjectId2, ObjectId1]
    相同。
© www.soinside.com 2019 - 2024. All rights reserved.