Getting confused with ksqlDB events and materialized views. I want to be notified in a dedicated topic / stream when a new high stock price occurs as determined in a table aggregate / materialized view but I'm getting the high price reported for every event rather than only when there is a new high price event.
Here is my working example / setup.
Create underlying stream and topic for stocks.
ksql> create stream stocks (symbol VARCHAR KEY, company VARCHAR, price DECIMAL(9, 2))
> WITH (KAFKA_TOPIC='stocks', PARTITIONS=1, VALUE_FORMAT='json');
Message
----------------
Stream created
----------------
add some initial data on stock prices for Acme Corp
ksql> insert into stocks (symbol, company, price) values ('ACME', 'Acme Corp', 111.11);
ksql> insert into stocks (symbol, company, price) values ('ACME', 'Acme Corp', 111.12);
ksql> insert into stocks (symbol, company, price) values ('ACME', 'Acme Corp', 111.13);
Print underlying topic to prove data is there.
ksql> print 'stocks' from beginning limit 3;
Key format: KAFKA_INT or KAFKA_STRING
Value format: JSON or KAFKA_STRING
rowtime: 2021/03/21 14:26:57.169 Z, key: 1094929733, value: {"COMPANY":"Acme Corp","PRICE":111.11}
rowtime: 2021/03/21 14:27:01.717 Z, key: 1094929733, value: {"COMPANY":"Acme Corp","PRICE":111.12}
rowtime: 2021/03/21 14:27:04.546 Z, key: 1094929733, value: {"COMPANY":"Acme Corp","PRICE":111.13}
Topic printing ceased
Create aggregate / materialized view to show highest stock prices.
ksql> create table stock_highs as
> select symbol, max(price) as high
> from stocks
> group by symbol
> emit changes;
Message
--------------------------------------------
Created query with ID CTAS_STOCK_HIGHS_115
--------------------------------------------
Query it for visual inspection.
ksql> select * from stock_highs where symbol = 'ACME';
+--------------+------------------------+
|SYMBOL |HIGH |
+--------------+------------------------+
|ACME |111.13 |
Query terminated
Use consumer (aka print STOCK_HIGHS) in a separate terminal (terminal 2) of to watch for changes to the stock high price.
ksql> print STOCK_HIGHS from beginning;
Key format: KAFKA_INT or KAFKA_STRING
Value format: JSON or KAFKA_STRING
rowtime: 2021/03/21 14:27:04.546 Z, key: 1094929733, value: {"HIGH":111.13}
Back in original terminal (terminal 1) with ksql client insert more data to force the stock high to be updated.
ksql> insert into stocks (symbol, company, price) values ('ACME', 'Acme Corp', 111.20);
ksql> insert into stocks (symbol, company, price) values ('ACME', 'Acme Corp', 111.15);
The above inserts should give a new high price of 111.20 and ignore the 111.15 price so, in my thinking and use case I'd want to get an event / message from the STOCK_HIGHS topic showing a new high stock price of 111.20 but not the 111.15 price. However, I get two new events in the consumer (terminal 2).
ksql> print STOCK_HIGHS from beginning;
Key format: KAFKA_INT or KAFKA_STRING
Value format: JSON or KAFKA_STRING
rowtime: 2021/03/21 14:27:04.546 Z, key: 1094929733, value: {"HIGH":111.13}
rowtime: 2021/03/21 14:37:51.234 Z, key: 1094929733, value: {"HIGH":111.20}
rowtime: 2021/03/21 14:39:03.301 Z, key: 1094929733, value: {"HIGH":111.20}
The problem is I really only want to be notified or "evented" when only new high prices are occuring that way I can have a consumer going off and doing something meaningful when there is a new high price established.