// Package main implement redis test data injection package main import ( "context" "fmt" "log" "github.com/RediSearch/redisearch-go/v2/redisearch" "github.com/redis/go-redis/v9" ) var ac *redisearch.Autocompleter // InitAutocompleterWithPool define func of initialize the Autocompleter with redigo pool func init() { // ac = redisearch.NewAutocompleterFromPool(pool, redisSearchDictName) ac = redisearch.NewAutocompleter("localhost:6379", redisSearchDictName) } const ( gridKeysSet = "grid_keys" zoneKeysSet = "zone_keys" stationKeysSet = "station_keys" componentNSPathKeysSet = "component_nspath_keys" componentTagKeysSet = "component_tag_keys" configKeysSet = "config_keys" measurementTagKeysSet = "measurement_tag_keys" // Grid -> Zone (e.g., grid1_zones_keys) gridZoneSetKeyFormat = "grid%d_zones_keys" // Zone -> Station (e.g., zone1_1_stations_keys) zoneStationSetKeyFormat = "zone%d_%d_stations_keys" // Station -> NSPath (e.g., station1_1_1_components_nspath_keys) stationNSPathKeyFormat = "station%d_%d_%d_components_nspath_keys" // NSPath -> CompTag (e.g., ns1_1_1_1_components_tag_keys) nsPathCompTagKeyFormat = "ns%d_%d_%d_%d_components_tag_keys" // CompTag -> Measurement (e.g., comptag1_1_1_1_1_measurement_keys) compTagMeasKeyFormat = "comptag%d_%d_%d_%d_%d_measurement_keys" ) const ( redisSearchDictName = "search_suggestions_dict" defaultScore = 1.0 ) var configMetrics = []any{ "component", "base_extend", "rated", "setup", "model", "stable", "bay", "craft", "integrity", "behavior", } func bulkInsertAllHierarchySets(ctx context.Context, rdb *redis.Client) error { log.Println("starting bulk insertion of Redis hierarchy sets") if err := insertStaticSets(ctx, rdb); err != nil { return fmt.Errorf("static set insertion failed: %w", err) } if err := insertDynamicHierarchy(ctx, rdb); err != nil { return fmt.Errorf("dynamic hierarchy insertion failed: %w", err) } if err := insertAllHierarchySuggestions(ac); err != nil { return fmt.Errorf("dynamic hierarchy insertion failed: %w", err) } log.Println("bulk insertion complete.") return nil } func insertStaticSets(ctx context.Context, rdb *redis.Client) error { // grid_keys if err := rdb.SAdd(ctx, gridKeysSet, "grid1", "grid2", "grid3").Err(); err != nil { return fmt.Errorf("sadd failed for %s: %w", gridKeysSet, err) } // zone_keys (3x3 = 9 members) zoneMembers := make([]any, 0, 9) for i := 1; i <= 3; i++ { for j := 1; j <= 3; j++ { zoneMembers = append(zoneMembers, fmt.Sprintf("zone%d_%d", i, j)) } } if err := rdb.SAdd(ctx, zoneKeysSet, zoneMembers...).Err(); err != nil { return fmt.Errorf("sadd failed for %s: %w", zoneKeysSet, err) } // config_keys if err := rdb.SAdd(ctx, configKeysSet, configMetrics...).Err(); err != nil { return fmt.Errorf("sadd failed for %s: %w", configKeysSet, err) } log.Println("Static sets (grid_keys, zone_keys, config_keys) inserted.") return nil } func insertDynamicHierarchy(ctx context.Context, rdb *redis.Client) error { allStationKeys := make([]any, 0, 27) allNSPathKeys := make([]any, 0, 81) allCompTagKeys := make([]any, 0, 243) allMeasurementTagKeys := make([]any, 0, 729) // S: Grid Prefix (1-3) for S := 1; S <= 3; S++ { // Grid-Zone Set Key: gridS_zones_keys gridZoneKey := fmt.Sprintf(gridZoneSetKeyFormat, S) gridZoneMembers := make([]any, 0, 3) // Y: Zone Index (1-3) for Y := 1; Y <= 3; Y++ { zoneID := fmt.Sprintf("%d_%d", S, Y) zoneMember := "zone" + zoneID gridZoneMembers = append(gridZoneMembers, zoneMember) // Zone-Station Set Key: zoneS_Y_stations_keys zoneStationKey := fmt.Sprintf(zoneStationSetKeyFormat, S, Y) zoneStationMembers := make([]any, 0, 3) // Z: Station Index (1-3) for Z := 1; Z <= 3; Z++ { stationID := fmt.Sprintf("%d_%d_%d", S, Y, Z) stationKey := "station" + stationID allStationKeys = append(allStationKeys, stationKey) zoneStationMembers = append(zoneStationMembers, stationKey) // Station-NSPath Set Key: stationS_Y_Z_components_nspath_keys stationNSPathKey := fmt.Sprintf(stationNSPathKeyFormat, S, Y, Z) stationNSMembers := make([]any, 0, 3) // D: NSPath Index (1-3) for D := 1; D <= 3; D++ { nsPathID := fmt.Sprintf("%s_%d", stationID, D) nsPathKey := "ns" + nsPathID allNSPathKeys = append(allNSPathKeys, nsPathKey) stationNSMembers = append(stationNSMembers, nsPathKey) // NSPath-CompTag Set Key: nsS_Y_Z_D_components_tag_keys nsCompTagKey := fmt.Sprintf(nsPathCompTagKeyFormat, S, Y, Z, D) nsCompTagMembers := make([]any, 0, 3) // I: CompTag Index (1-3) for I := 1; I <= 3; I++ { compTagID := fmt.Sprintf("%s_%d", nsPathID, I) compTagKey := "cmptag" + compTagID allCompTagKeys = append(allCompTagKeys, compTagKey) nsCompTagMembers = append(nsCompTagMembers, compTagKey) // CompTag-Measurement Set Key: comptagS_Y_Z_D_I_measurement_keys compTagMeasKey := fmt.Sprintf(compTagMeasKeyFormat, S, Y, Z, D, I) compTagMeasMembers := make([]any, 0, 3) // M: Measurement Index (1-3) for M := 1; M <= 3; M++ { measurementID := fmt.Sprintf("%s_%d", compTagID, M) measurementKey := "meas" + measurementID allMeasurementTagKeys = append(allMeasurementTagKeys, measurementKey) compTagMeasMembers = append(compTagMeasMembers, measurementKey) } if err := rdb.SAdd(ctx, compTagMeasKey, compTagMeasMembers...).Err(); err != nil { return fmt.Errorf("sadd failed for %s: %w", compTagMeasKey, err) } } if err := rdb.SAdd(ctx, nsCompTagKey, nsCompTagMembers...).Err(); err != nil { return fmt.Errorf("sadd failed for %s: %w", nsCompTagKey, err) } } if err := rdb.SAdd(ctx, stationNSPathKey, stationNSMembers...).Err(); err != nil { return fmt.Errorf("sadd failed for %s: %w", stationNSPathKey, err) } } if err := rdb.SAdd(ctx, zoneStationKey, zoneStationMembers...).Err(); err != nil { return fmt.Errorf("sadd failed for %s: %w", zoneStationKey, err) } } if err := rdb.SAdd(ctx, gridZoneKey, gridZoneMembers...).Err(); err != nil { return fmt.Errorf("sadd failed for %s: %w", gridZoneKey, err) } } // 插入所有顶层动态 Set (将所有成员一次性插入到全局 Set 中) if err := rdb.SAdd(ctx, stationKeysSet, allStationKeys...).Err(); err != nil { return fmt.Errorf("sadd failed for %s: %w", stationKeysSet, err) } if err := rdb.SAdd(ctx, componentNSPathKeysSet, allNSPathKeys...).Err(); err != nil { return fmt.Errorf("sadd failed for %s: %w", componentNSPathKeysSet, err) } if err := rdb.SAdd(ctx, componentTagKeysSet, allCompTagKeys...).Err(); err != nil { return fmt.Errorf("sadd failed for %s: %w", componentTagKeysSet, err) } if err := rdb.SAdd(ctx, measurementTagKeysSet, allMeasurementTagKeys...).Err(); err != nil { return fmt.Errorf("sadd failed for %s: %w", measurementTagKeysSet, err) } log.Printf("inserted %d stations, %d nspaths, %d comptags, and %d measurements.\n", len(allStationKeys), len(allNSPathKeys), len(allCompTagKeys), len(allMeasurementTagKeys)) return nil } func insertAllHierarchySuggestions(ac *redisearch.Autocompleter) error { suggestions := make([]redisearch.Suggestion, 0, 10000) // S: grid Index (1-3) for S := 1; S <= 3; S++ { gridStr := fmt.Sprintf("grid%d", S) suggestions = append(suggestions, redisearch.Suggestion{Term: gridStr, Score: defaultScore}) // Y: zone Index (1-3) for Y := 1; Y <= 3; Y++ { zoneStr := fmt.Sprintf("zone%d_%d", S, Y) gridZonePath := fmt.Sprintf("%s.%s", gridStr, zoneStr) suggestions = append(suggestions, redisearch.Suggestion{Term: gridZonePath, Score: defaultScore}) // Z: station Index (1-3) for Z := 1; Z <= 3; Z++ { stationStr := fmt.Sprintf("station%d_%d_%d", S, Y, Z) gridZoneStationPath := fmt.Sprintf("%s.%s", gridZonePath, stationStr) suggestions = append(suggestions, redisearch.Suggestion{Term: gridZoneStationPath, Score: defaultScore}) // D: nsPath Index (1-3) for D := 1; D <= 3; D++ { nsPathStr := fmt.Sprintf("ns%d_%d_%d_%d", S, Y, Z, D) gridZoneStationNSPath := fmt.Sprintf("%s.%s", gridZoneStationPath, nsPathStr) suggestions = append(suggestions, redisearch.Suggestion{Term: gridZoneStationNSPath, Score: defaultScore}) // I: compTag Index (1-3) for I := 1; I <= 3; I++ { compTagStr := fmt.Sprintf("comptag%d_%d_%d_%d_%d", S, Y, Z, D, I) fullCompTagPath := fmt.Sprintf("%s.%s", gridZoneStationNSPath, compTagStr) suggestions = append(suggestions, redisearch.Suggestion{Term: fullCompTagPath, Score: defaultScore}) for _, metric := range configMetrics { fullMetricPath := fmt.Sprintf("%s.%s", fullCompTagPath, metric) suggestions = append(suggestions, redisearch.Suggestion{Term: fullMetricPath, Score: defaultScore}) // J: measTag Index (1-3) for J := 1; J <= 3; J++ { measTagStr := fmt.Sprintf("comptag%d_%d_%d_%d_%d_%d", S, Y, Z, D, I, J) fullMeasurementPath := fmt.Sprintf("%s.%s", fullMetricPath, measTagStr) suggestions = append(suggestions, redisearch.Suggestion{Term: fullMeasurementPath, Score: defaultScore}) } } } } } } } log.Printf("generated %d suggestions. starting bulk insertion into dictionary '%s'.", len(suggestions), redisSearchDictName) // del ac suggestion ac.Delete() err := ac.AddTerms(suggestions...) if err != nil { return fmt.Errorf("failed to add %d suggestions: %w", len(suggestions), err) } return nil } func deleteAllHierarchySets(ctx context.Context, rdb *redis.Client) error { log.Println("starting to collect all Redis Set keys for deletion...") keysToDelete := []string{ gridKeysSet, zoneKeysSet, stationKeysSet, componentNSPathKeysSet, componentTagKeysSet, configKeysSet, measurementTagKeysSet, } for S := 1; S <= 3; S++ { keysToDelete = append(keysToDelete, fmt.Sprintf(gridZoneSetKeyFormat, S)) for Y := 1; Y <= 3; Y++ { keysToDelete = append(keysToDelete, fmt.Sprintf(zoneStationSetKeyFormat, S, Y)) for Z := 1; Z <= 3; Z++ { keysToDelete = append(keysToDelete, fmt.Sprintf(stationNSPathKeyFormat, S, Y, Z)) for D := 1; D <= 3; D++ { keysToDelete = append(keysToDelete, fmt.Sprintf(nsPathCompTagKeyFormat, S, Y, Z, D)) for I := 1; I <= 3; I++ { keysToDelete = append(keysToDelete, fmt.Sprintf(compTagMeasKeyFormat, S, Y, Z, D, I)) } } } } } log.Printf("collected %d unique keys. Starting batch deletion...", len(keysToDelete)) deletedCount, err := rdb.Del(ctx, keysToDelete...).Result() if err != nil { return fmt.Errorf("batch deletion failed: %w", err) } log.Printf("Successfully deleted %d keys (Sets) from Redis.", deletedCount) return nil } func main() { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", DB: 0, }) ctx := context.Background() if err := rdb.Ping(ctx).Err(); err != nil { log.Fatalf("could not connect to Redis: %v", err) } log.Println("connected to Redis successfully") if err := deleteAllHierarchySets(ctx, rdb); err != nil { log.Fatalf("error delete exist set before bulk insertion: %v", err) } if err := bulkInsertAllHierarchySets(ctx, rdb); err != nil { log.Fatalf("error during bulk insertion: %v", err) } }