Монго: вставлять, только если последний документ отличается
Есть ли способ сделать это в MongoDB:
Я хочу вставить документ, только если последний документ, отсортированный по полю, имеет другое значение для другого поля. Цель состоит в том, чтобы иметь коллекцию, в которой хранятся только переходы, а не все необработанные значения.
Пример:
Вот коллекция (с удобными для человека метками времени):
{ "created" : 1000, "lastUpdate" : 1000, "status" : "HEALTHY" }
{ "created" : 2000, "lastUpdate" : 2000, "status" : "ILL" }
{ "created" : 3000, "lastUpdate" : 3000, "status" : "HEALTHY" }
Тогда скажем, я получаю новый статус A
:
{ timestamp: 9999, "status": "HEALTHY" }
В случае A
, здесь нет status
переход, поэтому я хотел бы обновить коллекцию и иметь следующее:
{ "created" : 1000, "lastUpdate" : 1000, "status" : "HEALTHY" }
{ "created" : 2000, "lastUpdate" : 2000, "status" : "ILL" }
{ "created" : 3000, "lastUpdate" : 9999, "status" : "HEALTHY" }
Однако, если я получу новый статус B
это выглядит так:
{ timestamp: 9999, "status": "ILL" }
Я хочу зарегистрировать новый status
переход и сохранить новый документ в коллекции, потому что B
имеет другой status
чем последний обновленный документ (который имеет timestamp === 3000
а также status === "HEALTHY"
,
Коллекция будет выглядеть так:
{ "created" : 1000, "lastUpdate" : 1000, "status" : "HEALTHY" }
{ "created" : 2000, "lastUpdate" : 2000, "status" : "ILL" }
{ "created" : 3000, "lastUpdate" : 3000, "status" : "HEALTHY" }
{ "created" : 9999, "lastUpdate" : 9999, "status" : "ILL" }
Все, что я могу думать, это сделать findOne
чтобы получить последний обновленный документ, а затем update
или же insert
в зависимости от сравнения в памяти между извлеченным документом и вновь полученным объектом. Но это не подходит для параллелизма, поскольку другой процесс мог вставить другой документ между моими find
и мой insert/update
...
Есть ли какой-то паттерн или функция монго, о которой я не знаю, которая могла бы сделать это возможным?
1 ответ
Если вы вставляете или обновляете документ и включаете MMAP Storage Engine, тогда существует блокировка на уровне коллекции, в этом случае вы в безопасности. Но этот подход потерпит неудачу, если вы включили механизм хранения wiredtiger.