@@ -71,6 +71,62 @@ client.define(g);
7171
7272Then we may define a stream with customized configurations.
7373
74+ #### Define a how-warm-cold Group
75+
76+ Here illustrates how to use the lifecycle stages feature for hot-warm-cold data architecture:
77+
78+ ``` java
79+ // build a group sw_record for Stream with hot-warm-cold lifecycle stages
80+ Group g = Group . newBuilder(). setMetadata(Metadata . newBuilder(). setName(" sw_record" ))
81+ .setCatalog(Catalog . CATALOG_STREAM )
82+ .setResourceOpts(ResourceOpts . newBuilder()
83+ // Hot configuration
84+ .setShardNum(3 )
85+ // Default segment interval (will be overridden by stages if defined)
86+ .setSegmentInterval(
87+ IntervalRule . newBuilder()
88+ .setUnit(IntervalRule . Unit . UNIT_DAY )
89+ .setNum(1 ))
90+ // Default TTL (will be overridden by stages if defined)
91+ .setTtl(
92+ IntervalRule . newBuilder()
93+ .setUnit(IntervalRule . Unit . UNIT_DAY )
94+ .setNum(3 ))
95+ // Define lifecycle stages (hot → warm → cold)
96+ .addStages(LifecycleStage . newBuilder()
97+ .setName(" warm" )
98+ .setShardNum(2 ) // Fewer shards
99+ .setSegmentInterval(IntervalRule . newBuilder()
100+ .setUnit(IntervalRule . Unit . UNIT_DAY )
101+ .setNum(1 ))
102+ .setTtl(IntervalRule . newBuilder()
103+ .setUnit(IntervalRule . Unit . UNIT_DAY )
104+ .setNum(7 )) // Keep in warm for 7 days
105+ .setNodeSelector(" hdd-nodes" ) // Store on cheaper HDD nodes
106+ .build())
107+ .addStages(LifecycleStage . newBuilder()
108+ .setName(" cold" )
109+ .setShardNum(1 ) // Minimal shards for archived data
110+ .setSegmentInterval(IntervalRule . newBuilder()
111+ .setUnit(IntervalRule . Unit . UNIT_DAY )
112+ .setNum(7 )) // Larger segments for cold data
113+ .setTtl(IntervalRule . newBuilder()
114+ .setUnit(IntervalRule . Unit . UNIT_DAY )
115+ .setNum(30 )) // Keep in cold for 30 more days
116+ .setNodeSelector(" archive-nodes" ) // Store on archive nodes
117+ .setClose(true ) // Close segments that are no longer live
118+ .build()))
119+ .build();
120+ client. define(g);
121+ ```
122+
123+ This configuration creates a hot-warm-cold architecture where:
124+ - Hot stage: Data is stored on fast SSD nodes with many shards for 1 day, optimized for high query performance
125+ - Warm stage: Data moves to HDD nodes with fewer shards for 7 days, balanced between performance and cost
126+ - Cold stage: Data finally moves to archive nodes with minimal shards for 30 days, optimized for storage efficiency
127+
128+ Data automatically flows through these stages according to the defined TTLs. The total retention of data is 38 days (1+7+30).
129+
74130#### Define a Stream
75131``` java
76132// build a stream trace with above group
@@ -469,68 +525,64 @@ MeasureWrite measureWrite = client.createMeasureWrite("sw_metric", "service_cpm_
469525CompletableFuture<Void > f = measureBulkWriteProcessor. add(measureWrite);
470526f. get(10 , TimeUnit . SECONDS );
471527```
528+ # Property APIs
472529
473- ## Property APIs
474-
475- Property APIs are used to store key-value pairs.
476-
477- ### Apply(Create/Update)
478-
479- ` apply ` will always succeed whenever the property exists or not.
480- The old value will be overwritten if already existed, otherwise a new value will be set.
530+ Before using properties, you need to define a property schema:
481531
482532``` java
483- Property property = Property . create(" default" , " sw" , " ui_template" )
484- .addTag(TagAndValue . newStringTag(" name" , " hello" ))
485- .addTag(TagAndValue . newStringTag(" state" , " successd" ))
486- .build();
487- this . client. apply(property); // created:true tagsNum:2
533+ // Define property schema
534+ BanyandbDatabase . Property propertyDef =
535+ BanyandbDatabase . Property . newBuilder()
536+ .setMetadata(Metadata . newBuilder()
537+ .setGroup(" default" )
538+ .setName(" ui_template" ))
539+ .setTagType(TagType . TAG_TYPE_STRING )
540+ .build();
541+
542+ client. define(propertyDef);
488543```
489544
490- The operation supports updating partial tags.
545+ After defining the schema, you can apply (create/update) properties:
491546
492547``` java
493- Property property = Property . create(" default" , " sw" , " ui_template" )
494- .addTag(TagAndValue . newStringTag(" state" , " failed" ))
548+ // Apply a property (create or update)
549+ Property property = Property . newBuilder()
550+ .setMetadata(Metadata . newBuilder()
551+ .setGroup(" default" )
552+ .setName(" ui_template" ))
553+ .setId(" dashboard-1" )
554+ .setTagValue(BanyandbModel . TagValue . newBuilder()
555+ .setStr(" template-data-json" ))
495556 .build();
496- this . client. apply(property); // created:false tagsNum:1
497- ```
498-
499- ### Query
500557
501- Property can be queried via ` Client.findProperty ` ,
502-
503- ``` java
504- BanyandbProperty . QueryResponse resp = client. query(BanyandbProperty . QueryRequest . newBuilder()
505- .addGroups(" default" )
506- .setContainer(" sw" )
507- .addIds(" ui_template" )
508- .build());
558+ ApplyResponse response = client. apply(property);
509559```
510560
511- The query operation could filter tags,
561+ You can also apply with a specific strategy:
512562
513563``` java
514- BanyandbProperty . QueryResponse resp = client. query(BanyandbProperty . QueryRequest . newBuilder()
515- .addGroups(" default" )
516- .setContainer(" sw" )
517- .addIds(" ui_template" )
518- .addTagProjection(" state" )
519- .build());
564+ // Apply with merge strategy
565+ ApplyResponse response = client. apply(property, Strategy . STRATEGY_MERGE );
520566```
521567
522- ### Delete
523-
524- Property can be deleted by calling ` Client.deleteProperty ` ,
568+ Query properties:
525569
526570``` java
527- this . client. deleteProperty(" default" , " sw" , " ui_template" ); // deleted:true tagsNum:2
571+ // Query properties
572+ BanyandbProperty . QueryRequest queryRequest = BanyandbProperty . QueryRequest . newBuilder()
573+ .setMetadata(Metadata . newBuilder()
574+ .setGroup(" default" )
575+ .setName(" ui_template" ))
576+ .build();
577+
578+ BanyandbProperty . QueryResponse queryResponse = client. query(queryRequest);
528579```
529580
530- The delete operation could remove specific tags instead of the whole property.
581+ Delete a property:
531582
532583``` java
533- this . client. deleteProperty(" default" , " sw" , " ui_template" , " state" ); // deleted:true tagsNum:1
584+ // Delete a property
585+ DeleteResponse deleteResponse = client. deleteProperty(" default" , " ui_template" , " dashboard-1" );
534586```
535587
536588# Compiling project
0 commit comments