Атомный запрос для всех документов коллекции + отслеживание дальнейших изменений - PullRequest
0 голосов
/ 11 июня 2019

Наше Java-приложение сохраняет свои конфигурации в коллекциях MongoDB. Когда приложение запускается, оно считывает все конфигурации из MongoDB и кэширует их в Картах. Мы хотели бы использовать API потока изменений, чтобы иметь возможность также следить за обновлениями коллекций конфигураций. Итак, при запуске приложения сначала мы хотели бы получить все конфигурации, а теперь - отслеживать любые дальнейшие изменения.
Есть ли простой способ выполнить следующие атомарно :

  1. A find(), который извлекает все конфигурации (документы)
  2. Запустите watch(), который будет отправлять все дальнейшие обновления

Под атомарным пониманием я подразумеваю - потенциально не пропуская обновления (от 1 до 2 кто-то может обновить коллекцию с новой конфигурацией).

1 Ответ

0 голосов
/ 13 июня 2019

Чтобы убедиться, что я не теряю уведомлений об обновлениях, я обнаружил, что могу использовать watch().startAtOperationTime(serverTime) (для MongoDB 4.0 или более поздней версии) следующим образом.

  1. Запросить сервер MongoDB для текущего временис помощью такой команды, как Document hostInfoDoc = mongoTemplate.executeCommand(new Document("hostInfo", 1))
  2. Запрос всех интересных документов: List<C> configList = mongoTemplate.findAll(clazz);
  3. Извлечение времени сервера из hostInfoDoc: BsonTimestamp serverTime = (BsonTimestamp) hostInfoDoc.get("operationTime");
  4. Запуск настроенного потока измененийс сохраненным временем сервера ChangeStreamIterable<Document> changes = eventCollection.watch().startAtOperationTime(serverTime);

Так как 1 заканчивается до 2 запусков, мы знаем, что документы, которые были возвращены 2, были, по крайней мере, такими же или более свежими, чем документы на этом времени сервера.И любые обновления, которые произошли в это или после этого времени сервера, будут отправлены нам потоком изменений (я не хочу снова запускать избыточные обновления, потому что я использую карту в качестве кэша, поэтому дополнительные операции добавления / удаления не будут иметь значенияДо тех пор, пока прибывает последнее действие).

Думаю, я мог бы также использовать watch().resumeAfter(_idOfLastAddedDoc) (не пробовал).Я не использовал этот подход из-за следующего сценария: коллекция пуста, и первый документ добавляется после получения всех (ни одного) документов и перед запуском watch().В этом случае у меня нет предыдущего документа _id для использования в качестве маркера резюме.

...