Через пару дней я пришел к решению этой проблемы. Вместо того, чтобы поддерживать список _ids, мои методы имеют свои ограничения.
Это код, который мы генерируем для нашего собственного монго _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;
}
Самая сложная часть этой функции - поймать так много возможных крайних случаев. И есть ограничения на вставку строк, чтобы две существующие строки не создавались слишком близко. И будут проблемы, если приложение будет расширяться с увеличением количества пользователей. Но он будет работать для небольшой группы пользователей и как дополнительная функция, когда это необходимо.
В будущем, если мы сможем создать более уникальный генератор идентификаторов, который мы сможем вставить без ограничений. Что касается моих исследований, никто никогда не придумывал что-то подобное, но мне потребовались дни, чтобы разобраться. Я надеюсь, что эти результаты сэкономят вам время на исследования.