Typical streaming query patterns

This section contains minimal examples of streaming queries for the most common scenarios. First, a basic pattern for reading data from a topic is described, followed by variants of full data processing: data processing and writing results to a topic in JSON format, to a topic as a string, and to a table. Each example can be used as a starting point for your own tasks.

The examples below use local and external topics. Notation:

  • ext_source — a pre-created external data source
  • input_topic — the topic from which data is read
  • output_topic — the topic where results are written
  • output_table — the YDB table where results are written

Reading data from a topic

Reading structured messages is done using SELECT ... FROM ... WITH (FORMAT, SCHEMA). The WITH block specifies the input data format and schema — which fields are expected in each message and their types.

The following fragment is used inside CREATE STREAMING QUERY in the DO BEGIN ... END DO block:

SELECT
    Id,
    Name
FROM
    topic_name  -- local topic; for external: ext_source.topic_name
WITH (
    FORMAT = json_each_row,
    SCHEMA = (
        Id Uint64 NOT NULL,
        Name Utf8 NOT NULL
    )
);

For more details on formats: Data formats for reading/writing from topics.

This pattern is used in all subsequent examples.

Writing to a topic (JSON)

The query reads events from the input topic, forms a JSON object from individual fields, and writes the result to the output topic. The AsStruct function creates a structure from the specified fields, Yson::From converts it to Yson, Yson::SerializeJson serializes it to a JSON string, and ToBytes converts it to the String type, which is required for writing to the topic.

CREATE STREAMING QUERY write_json_example AS
DO BEGIN

INSERT INTO ext_source.output_topic -- or local topic output_topic
SELECT
    -- Building JSON from individual fields
    ToBytes(Unwrap(Yson::SerializeJson(Yson::From(
        AsStruct(Id AS id, Name AS name)
    ))))
FROM
    input_topic -- or external topic ext_source.input_topic
WITH (
    FORMAT = json_each_row,  -- Input data format
    SCHEMA = (               -- Input data schema
        Id Uint64 NOT NULL,
        Name Utf8 NOT NULL
    )
);

END DO

For more details on functions:

Writing to a topic (string)

The query reads events from the input topic and writes one field as a string to the output topic. To write strings to a topic, SELECT must return a single column of type String or Utf8.

CREATE STREAMING QUERY write_utf8_example AS
DO BEGIN

INSERT INTO output_topic -- or external topic ext_source.output_topic
SELECT
    Name
FROM
    ext_source.input_topic -- or local topic input_topic
WITH (
    FORMAT = json_each_row,  -- Input data format
    SCHEMA = (               -- Input data schema
        Id Uint64 NOT NULL,
        Name Utf8 NOT NULL
    )
);

END DO

For more details on write formats: Formats for writing data.

Writing to a table

The query reads events from the topic and writes them to the output_table table. The table must be created in advance with a schema matching the selected columns.

Warning

Writing to tables in streaming queries is supported only in UPSERT mode. The INSERT INTO operation is not supported, because during reprocessing of events (the at-least-once guarantee) it would lead to duplicate rows. With UPSERT, if a row with such a primary key already exists, it will be updated; otherwise, a new row will be inserted, and INSERT INTO will fail with an error.

CREATE STREAMING QUERY write_table_example AS
DO BEGIN

-- Writing to table (only UPSERT, INSERT not supported)
UPSERT INTO output_table
SELECT
    Id,
    Name
FROM
    ext_source.input_topic -- or local topic input_topic
WITH (
    FORMAT = json_each_row,  -- Input data format
    SCHEMA = (               -- Input data schema
        Id Uint64 NOT NULL,
        Name Utf8 NOT NULL
    )
);

END DO

For more details: Writing to tables.

See also