Quick start: reading and writing to topics
In this guide, you will create your first streaming query.
The query will:
- read events from the input topic
- filter only errors
- count the number of errors per server over 10 minutes
- write the result to the output topic.
Events arrive in JSON format with fields: time, logging level, and server name.
You will perform the following steps:
- Create topics;
- Create the streaming query;
- Check query state;
- Produce sample input;
- Read the output topic;
- Delete the streaming query.
Prerequisites
To run the examples, you will need:
- A running YDB database — see quick start;
- The
enable_streaming_queriesfeature flag enabled.
docker run -d --rm --name ydb-local -h localhost \
--platform linux/amd64 \
-p 2135:2135 -p 2136:2136 -p 8765:8765 -p 9092:9092 \
-v $(pwd)/ydb_certs:/ydb_certs \
-e GRPC_TLS_PORT=2135 -e GRPC_PORT=2136 -e MON_PORT=8765 \
-e YDB_FEATURE_FLAGS=enable_streaming_queries \
ydbplatform/local-ydb:25.4
./local_ydb deploy \
--ydb-working-dir=/absolute/path/to/working/directory \
--ydb-binary-path=/path/to/kikimr/driver \
--enable-feature-flag=enable_streaming_queries
Note
The examples use the quickstart profile. To learn more, see Creating a profile to connect to a test database.
Step 1. Creating topics
Create the input and output topics:
CREATE TOPIC input_topic;
CREATE TOPIC output_topic;
Verify that the topics are created:
./ydb --profile quickstart scheme ls
Step 2. Create the streaming query
Create a streaming query with CREATE STREAMING QUERY:
CREATE STREAMING QUERY query_example AS
DO BEGIN
$number_errors = SELECT
Host,
COUNT(*) AS ErrorCount,
CAST(HOP_START() AS String) AS Ts -- Start time of the window corresponding to the aggregation result
FROM
input_topic
WITH (
FORMAT = json_each_row,
SCHEMA = (
Time String NOT NULL,
Level String NOT NULL,
Host String NOT NULL
)
)
WHERE
Level = "error"
GROUP BY
HOP(CAST(Time AS Timestamp), "PT600S", "PT600S", "PT0S"), -- Number of errors on non-overlapping windows of 10 minutes length
Host;
INSERT INTO
output_topic
SELECT
ToBytes(Unwrap(Yson::SerializeJson(Yson::From(TableRow())))) -- Serialization of all columns into JSON
FROM
$number_errors;
END DO
More details:
GROUP BY HOPaggregation andHOP_START— GROUP BY ... HOP.- Writing to a topic — Formats for writing data.
- JSON serialization: TableRow, Yson::From, Yson::SerializeJson, Unwrap, ToBytes.
Step 3. Check query state
Check query state in the streaming_queries system table:
SELECT
Path,
Status,
Issues,
Run
FROM
`.sys/streaming_queries`
Make sure that the Status field has the value RUNNING. Otherwise, check the Issues field.
If the query is in SUSPENDED status or the Issues field contains errors, see the error diagnostics section.
Step 4. Produce sample input
Write test messages to the topic using the YDB CLI:
echo '{"Time": "2025-01-01T00:00:00.000000Z", "Level": "error", "Host": "host-1"}' | ./ydb --profile quickstart topic write input_topic
echo '{"Time": "2025-01-01T00:04:00.000000Z", "Level": "error", "Host": "host-2"}' | ./ydb --profile quickstart topic write input_topic
echo '{"Time": "2025-01-01T00:08:00.000000Z", "Level": "error", "Host": "host-1"}' | ./ydb --profile quickstart topic write input_topic
echo '{"Time": "2025-01-01T00:12:00.000000Z", "Level": "error", "Host": "host-2"}' | ./ydb --profile quickstart topic write input_topic
echo '{"Time": "2025-01-01T00:12:00.000000Z", "Level": "error", "Host": "host-1"}' | ./ydb --profile quickstart topic write input_topic
Results appear in the output topic after the 10-minute aggregation window closes.
Step 5. Read the output topic
Read data from the output topic:
./ydb --profile quickstart topic read output_topic --partition-ids 0 --start-offset 0 --limit 10 --format newline-delimited
Expected result:
{"ErrorCount":1,"Host":"host-2","Ts":"2025-01-01T00:00:00Z"}
{"ErrorCount":2,"Host":"host-1","Ts":"2025-01-01T00:00:00Z"}
Step 6. Delete the query
Delete the query with DROP STREAMING QUERY:
DROP STREAMING QUERY query_example;
What's next
- Explore the data formats supported in streaming queries.
- Learn how to enrich data with a reference from a local table or from S3.
- Learn how to write results to tables.