feat(go): reuse parsed fields across projections

This commit is contained in:
lingniu
2026-07-03 17:38:50 +08:00
parent 368b18fc96
commit 378a5d5e57
11 changed files with 620 additions and 64 deletions

View File

@@ -348,20 +348,10 @@ func (r *Repository) setJSON(ctx context.Context, key string, value any, ttl tim
}
func (r *Repository) setKV(ctx context.Context, vin string, env envelope.FrameEnvelope, parsed map[string]any) error {
rows := realtimeKVFields(env, parsed)
if len(rows) == 0 {
return nil
}
values := make(map[string]any, len(rows))
types := make(map[string]any, len(rows))
for _, row := range rows {
field := realtimeKVFieldPath(row.Domain, row.Field)
if field == "" {
continue
}
values[field] = row.Value
types[field] = row.ValueType
if len(env.ParsedFields) == 0 && len(parsed) > 0 {
env.Parsed = parsed
}
values, types := realtimeKVMapsForEnvelope(env)
if len(values) == 0 {
return nil
}
@@ -383,8 +373,7 @@ func (r *Repository) setKV(ctx context.Context, vin string, env envelope.FrameEn
}
func (r *Repository) setFastProjection(ctx context.Context, vehicleKey string, vin string, env envelope.FrameEnvelope) error {
rows := realtimeKVFields(env, env.Parsed)
values, types := realtimeKVMaps(rows)
values, types := realtimeKVMapsForEnvelope(env)
eventTimeMS := eventTimeOrReceivedMS(env)
offlineAfterMS := env.ReceivedAtMS + r.cfg.ttl().Milliseconds()
online := OnlineStatus{
@@ -435,6 +424,30 @@ func (r *Repository) setFastProjection(ctx context.Context, vehicleKey string, v
return err
}
func realtimeKVMapsForEnvelope(env envelope.FrameEnvelope) (map[string]any, map[string]any) {
if fields, fieldTypes, ok := ParsedFieldsForEnvelope(env); ok {
values := make(map[string]any, len(fields))
types := make(map[string]any, len(fields))
for field, value := range fields {
if strings.TrimSpace(field) == "" {
continue
}
stringValue, valueType, ok := stringifyKVValue(value)
if !ok {
continue
}
values[field] = stringValue
if typed := strings.TrimSpace(fieldTypes[field]); typed != "" {
types[field] = typed
} else {
types[field] = valueType
}
}
return values, types
}
return nil, nil
}
func realtimeKVMaps(rows []RealtimeKVField) (map[string]any, map[string]any) {
values := make(map[string]any, len(rows))
types := make(map[string]any, len(rows))