Apache Ignite Continuous Queries: Как получить имена полей и значения полей в обновлениях слушателя при наличии динамических полей?
Я работаю над POC над тем, стоит ли нам использовать Apache Ignite для коммерческого и корпоративного использования. Однако есть вариант использования, для которого мы пытаемся найти ответ.
Предпосылками
Динамическое создание таблиц, т.е. могут появиться новые поля, которые будут помещены в кэш. Это означает, что нет предварительно скомпилированного POJO(Модель), определяющего атрибуты таблицы / кэша.
Случай использования
Я хотел бы написать непрерывный запрос SELECT, где он дает мне результаты, которые были изменены. Поэтому я написал этот запрос, но проблема в том, что, когда слушатель получает уведомление, я не могу найти все имена полей, которые были изменены из любого вызова метода. Я хотел бы иметь возможность получить все имена полей и значения полей в какой-то карте, которую я могу использовать, а затем отправить в другие системы.
1 ответ
Вы можете отслеживать все измененные значения полей, используя двоичный объект и непрерывный запрос:
IgniteCache<Integer, BinaryObject> cache = ignite.cache("person").withKeepBinary();
ContinuousQuery<Integer, BinaryObject> query = new ContinuousQuery<>();
query.setLocalListener(events -> {
for (CacheEntryEvent<? extends Integer, ? extends BinaryObject> event : events) {
BinaryType type = ignite.binary().type("Person");
if (event.getOldValue() != null && event.getValue() != null) {
HashMap<String,Object> oldProps = new HashMap<>();
HashMap<String,Object> newProps = new HashMap<>();
for (String field : type.fieldNames()) {
oldProps.put(field,event.getOldValue().field(field));
newProps.put(field,event.getValue().field(field));
}
com.google.common.collect.MapDifference<Object, Object> diff = com.google.common.collect.Maps.difference(oldProps, newProps);
System.out.println(diff.entriesDiffering());
}
}
});
cache.query(query);
cache.put(1, ignite.binary().builder("Person").setField("name","Alice").build());
cache.put(1, ignite.binary().builder("Person").setField("name","Bob").build());