Одна идея: создать отдельную коллекцию cancelled
и переместить все отмененные встречи в эту коллекцию.
Если необходимо назначить новую встречу, сначала найдите в этой коллекции cancelled
любые открытые места, подлежащие на отмены. Если ничего подходящего не найдено, переходите к самой поздней дате окончания в соответствии с вашим текущим методом.
Иллюстрация:
> db.appointments.find()
{ "_id" : 0, "start" : 1, "end" : 2, "duration" : 1, "name": "John" }
{ "_id" : 1, "start" : 2, "end" : 4, "duration" : 2, "name": "Jane" }
{ "_id" : 2, "start" : 4, "end" : 5, "duration" : 1, "name": "Jack" }
// Jane cancelled the appt with _id 1
> c = db.appointments.findOne({_id: 1})
> db.cancelled.insert(c)
> db.appointments.deleteOne({_id: 1})
// current state of appointments
> db.appointments.find()
{ "_id" : 0, "start" : 1, "end" : 2, "duration" : 1, "name": "John" }
{ "_id" : 2, "start" : 4, "end" : 5, "duration" : 1, "name": "Jack" }
// Bob wanted to make an appointment spanning two "time units". Is it available?
> db.cancelled.findOne({duration: 2})
{ "_id" : 1, "start" : 2, "end" : 4, "duration" : 2, "name" : "Jane" }
// If Bob agreed to take over Jane's time slot
// reinsert the document from "cancelled" to "appointments", changing the name
> a = db.cancelled.findOne({duration: 2})
> a.name = "Bob"
> db.appointments.insert(a)
> db.cancelled.deleteOne({_id:1})
// end state of appointments
> db.appointments.find().sort({start: 1})
{ "_id" : 0, "start" : 1, "end" : 2, "duration" : 1, "name": "John" }
{ "_id" : 1, "start" : 2, "end" : 4, "duration" : 2, "name": "Bob" }
{ "_id" : 2, "start" : 4, "end" : 5, "duration" : 1, "name": "Jack" }
Обратите внимание, что на этой иллюстрации я также записал продолжительность каждой встречи поэтому их можно эффективно искать. Конечное состояние _id: 1
от Джейн было заменено Бобом, в коллекции cancelled
ничего нет.
Чтобы убедиться, что обе коллекции appointments
и cancelled
обновлены правильно, вы можете захотеть использовать Транзакции , доступные с MongoDB 4.0.