几天后,我找到了这个解决方案。我的方法不是维护 _ids 列表,而是有其局限性。
这是我们根据前后时间戳生成自己的mongo_id的代码
let newId;
let canInsert = true;
if (this.state.insertIndex !== undefined) {
if (this.state.insertIndex == 0 && rows.length >=2) {
const before = parseInt(rows[Math.max(this.state.insertIndex, 0)]._id.toString().substring(0, 8), 16) * 1000
const after = parseInt(rows[Math.min(this.state.insertIndex + 1, rows.length - 1)]._id.toString().substring(0, 8), 16) * 1000;
if (after - before > 1000) {
const timestampAsInteger = Math.floor(Math.random() * (after - before + 1) + before);
if (timestampAsInteger - before > 1000) {
newId = Math.floor(timestampAsInteger / 1000).toString(16) + "0000000000000000";
} else {
canInsert = false;
}
} else {
canInsert = false;
}
} else if (this.state.insertIndex < rows.length - 1) {
const before = parseInt(rows[Math.max(this.state.insertIndex, 0)]._id.toString().substring(0, 8), 16) * 1000
const after = parseInt(rows[Math.min(this.state.insertIndex + 1, rows.length - 1)]._id.toString().substring(0, 8), 16) * 1000;
if (after - before > 1000) {
const timestampAsInteger = Math.floor(Math.random() * (after - before + 1) + before);
if (timestampAsInteger - before > 1000) {
newId = Math.floor(timestampAsInteger / 1000).toString(16) + "0000000000000000";
} else {
canInsert = false;
}
} else {
canInsert = false;
}
}
}
我知道上面的代码很难阅读,但是有很多边缘情况,特别是由于 newId 生成方法,我们有两个时间戳至少应该有一个间隔 > 1000 的限制,否则会导致问题。
在 fetch 中,我们需要检查是否生成了 newId,否则我们将在最后一行添加
let index = this.state.insertIndex == undefined? Math.max(rows.length, 0): Math.max(this.state.insertIndex + 1, 0);
json["value"] = index;
rows = canInsert ? update(rows, {$splice: [[index, 0, json]]}): update(rows, { $push: [json] });
if (canInsert) {
this.showMessage("The project name cannot be empty");
} else {
this.showMessage("Impossible to insert, add last instead");
}
在我们的后端,将 _id 设置为我们的 newId
if (req.body.newId) {
initialData['_id'] = req.body.newId;
}
这个特性最困难的部分是捕捉这么多可能的边缘情况。并且存在插入行的限制,两个已存在的行可能不会太紧密地生成。如果应用程序随着更多用户不断扩大规模,就会出现问题。但它适用于较小的用户组,并在需要时作为可选功能。
将来如果我们能想出一个更独特的 id 生成器,我们可以不受限制地插入。据我研究,从来没有人想出过这样的事情,但我花了几天时间才弄清楚这些事情。我希望这一发现可以为您节省几天的研究时间。