咨询Go语言中Gremlin查询结果的简化处理方法
Go Gremlin查询结果解析优化问题
以下是一段在Go中执行Gremlin查询并解析结果的代码:
func (n NeptuneGremlinGraph) Query(assetID string, version string, entityID string) ([]hz.Component, error) { defer utils.TimeTracker(time.Now(), fmt.Sprintf("Graph Query")) g := gremlin.Traversal_().WithRemote(n.connection) anonT := gremlin.T__ results, err := g.V(makeId(assetID, version, entityID)). Repeat(anonT.As("a").InE().OutV().SimplePath()). Emit().Until(anonT.OutE().Count().Is(0)). Filter(anonT.HasLabel("Component")). Project("entity", "component"). By(anonT.Select("a").ElementMap()). By(anonT.ElementMap()). ToList() if err != nil { return nil, err } cnt := 0 for _, r := range results { var entityID, componentID, value string if m, ok := r.Data.(map[any]any); ok { if entity, ok := m["entity"]; ok { if entity, ok := entity.(map[any]any); ok { if id, ok := entity["id"]; ok { if id, ok := id.(string); ok { _, _, entityID = splitId(id) } } } } if component, ok := m["component"]; ok { if component, ok := component.(map[any]any); ok { if id, ok := component["component_id"]; ok { if id, ok := id.(string); ok { componentID = id } } if v, ok := component["value"]; ok { if v, ok := v.(string); ok { value = v } } } } log.Printf("%s, %s, %s\n", entityID, componentID, value) } else { log.Printf("not a map\n") } } log.Printf("path cnt = %d\n", cnt) return nil, nil }
目前我需要逐层断言map[any]any来解析结果,过程非常繁琐。虽然可以编写辅助方法优化,但想确认:是否遗漏了Gremlin driver的Result对象中可简化该过程的内置方法?
回答
Go的Gremlin driver(如tinkerpop/gremlin-go)的Result对象本身并没有提供直接将Data字段自动映射到结构体或简化多层类型断言的内置方法,你目前的手动断言方式是这类场景下的常规操作,但可以通过以下几种方式优化:
泛型辅助函数简化重复断言
编写通用的取值函数,减少嵌套的if-ok判断代码:func getStringFromMap(m map[any]any, key string) string { val, exists := m[key] if !exists { return "" } strVal, isStr := val.(string) if !isStr { return "" } return strVal }后续解析时直接调用该函数,比如
entityIDPart := getStringFromMap(entityMap, "id"),大幅简化代码层级。优化Gremlin查询减少解析层级
在查询阶段就精准指定需要返回的字段,而非返回完整的ElementMap。例如将:By(anonT.Select("a").ElementMap())修改为:
By(anonT.Select("a").Values("id"))这样结果会直接返回
id的字符串值,无需后续多层断言。自定义结构体+映射库自动解析
定义与查询结果结构匹配的结构体,使用mapstructure这类第三方库自动完成map[any]any到结构体的映射:import "github.com/mitchellh/mapstructure" type QueryResult struct { Entity struct { ID string `mapstructure:"id"` } `mapstructure:"entity"` Component struct { ComponentID string `mapstructure:"component_id"` Value string `mapstructure:"value"` } `mapstructure:"component"` }然后在循环中直接解析:
var result QueryResult if err := mapstructure.Decode(r.Data, &result); err == nil { // 直接使用result.Entity.ID、result.Component.ComponentID等字段 _, _, entityID = splitId(result.Entity.ID) componentID = result.Component.ComponentID value = result.Component.Value }
内容的提问来源于stack exchange,提问作者Michael Burbidge
相关产品推荐
相关产品推荐

