Go SDK与Neo4j浏览器Cypher查询结果不一致(关系缺失)
Neo4j Go SDK查询结果缺失Relationship问题
环境信息
- Neo4j版本:Neo4j Kernel 5.12.0 community
- 部署模式:单实例
- Go Driver版本:v5.12.0
- 操作系统:CentOS
问题现象
使用Go SDK执行Cypher查询时,获取的数据结果与Neo4j浏览器中的结果不一致,存在多个Relationship缺失。浏览器查询结果中存在的三个Relationship,在Go SDK返回结果中完全没有。
执行的Cypher语句
MATCH (n1:AAA_IngressOfSecurityGroup {AssetsAccountId:"aaaa"})-[:IngressOfSecurityGroup]->(n2:AAA_SecurityGroup {AssetsAccountId:"aaaa"})-[:SecurityGroupOfNetworkInterface]->(n3:AAA_NetworkInterface {AssetsAccountId:"aaaa"})-[:NetworkInterfaceOfCvm]->(n4:AAA_CvmInstance {AssetsAccountId:"aaaa",AssetUniqueId:"aaaa-165d2740e7fa",AssetsVersion:"1702108924"}) WHERE n4.InstanceState = 'RUNNING' AND n4.RestrictState = 'NORMAL' AND n1.Action = 'ACCEPT' AND (n1.Ipv6CidrBlock = "::/0" OR n1.CidrBlock = "0.0.0.0/0") AND toLower(n1.Port) = 'all' AND (toLower(n1.Protocol) = 'tcp' or toLower(n1.Protocol) = 'udp' or toLower(n1.Protocol)= 'all' ) WITH n1, n2, n3, n4 WHERE ALL (groupId IN n3.GroupSet WHERE NOT EXISTS { MATCH (n2_other:AAA_SecurityGroup {AssetsAccountId:"aaaa", SecurityGroupId: groupId})-[:IngressOfSecurityGroup]->(n1_other:AAA_IngressOfSecurityGroup) WHERE n1_other.Action = 'DROP' AND ((n1_other.CidrBlock = "0.0.0.0/0" OR n1_other.Ipv6CidrBlock = "::/0") AND toLower(n1_other.Port) = 'all') AND NOT EXISTS { MATCH (n1_smaller:AAA_IngressOfSecurityGroup)-[:IngressOfSecurityGroup]->(n2_other) WHERE toInteger(n1_smaller.PolicyIndex) < toInteger(n1_other.PolicyIndex) } } ) OPTIONAL MATCH p2 = (n7:AAA_PublicIp {AssetsAccountId:"aaaa"})-[:PublicIpToVpc]->(n6:AAA_Vpc {AssetsAccountId:"aaaa"})-[:SubnetsInVPC]->(n5:AAA_Subnet {AssetsAccountId:"aaaa"})-[:NetworkInterfaceInSubnet]->(n3) WHERE p2 IS NOT NULL OPTIONAL MATCH p3 = (n8:AAA_Eip {AssetsAccountId:"aaaa"})-[:EipOToVpc]->(n6)-[:SubnetsInVPC]->(n5)-[:NetworkInterfaceInSubnet]->(n3) WHERE p3 IS NOT NULL WITH DISTINCT n4, n1, n2, n3, n6, n7, p2, p3 RETURN n1, n2, n3,n4, n6, n7, p2, p3
处理返回结果的Go代码
result, session, err := global.Neo4j.RunCypherQuery(body.Cypher, nil) if err != nil { logger.Log.Error("RunCypherQuery error: " + err.Error()) response := responses.NewErrorResponse(responses.StatusCodeUnknownErr, err.Error()) c.JSON(http.StatusOK, response) return } var nodes []neo4j.Node var relationships []neo4j.Relationship seenNodes := make(map[int64]bool) seenRelationships := make(map[int64]bool) for result.Next() { record := result.Record() for _, value := range record.Values { if value == nil { continue } switch v := value.(type) { case neo4j.Node: if _, found := seenNodes[v.Id]; !found { seenNodes[v.GetId()] = true nodes = append(nodes, v) } case neo4j.Relationship: if _, found := seenRelationships[v.Id]; !found { seenRelationships[v.GetId()] = true relationships = append(relationships, v) } case neo4j.Path: for _, node := range v.Nodes { if _, found := seenNodes[node.Id]; !found { seenNodes[node.GetId()] = true nodes = append(nodes, node) } } for _, rel := range v.Relationships { if _, found := seenRelationships[rel.Id]; !found { seenRelationships[rel.GetId()] = true relationships = append(relationships, rel) } } case []interface{}: for _, item := range v { switch elem := item.(type) { case neo4j.Node: if _, found := seenNodes[elem.GetId()]; !found { seenNodes[elem.GetId()] = true nodes = append(nodes, elem) } case neo4j.Relationship: if _, found := seenRelationships[elem.GetId()]; !found { seenRelationships[elem.GetId()] = true relationships = append(relationships, elem) } default: logger.Log.Error("Unexpected type in []interface{}: %T", item) response := responses.NewErrorResponse(responses.StatusCodeUnknownErr, errors.New(fmt.Sprintf("Unexpected type in []interface{}: %T", item)).Error()) c.JSON(http.StatusOK, response) return } } default: logger.Log.Error("Unexpected type: %T", v) response := responses.NewErrorResponse(responses.StatusCodeUnknownErr, errors.New(fmt.Sprintf("Unexpected type: %T", v)).Error()) c.JSON(http.StatusOK, response) return } } }
RunCypherQuery方法实现
func (c *Client) RunCypherQuery(query string, params map[string]interface{}) (neo4j.Result, neo4j.Session, error) { session := c.driver.NewSession(neo4j.SessionConfig{}) fmt.Println(query) result, err := session.Run(query, params) if err != nil { return nil, session, err } return result, session, nil }
结果差异说明
Neo4j浏览器查询结果中存在三个Relationship(对应原描述截图中红色叉号标记位置),但Go SDK返回的结果中完全缺失这些Relationship数据。
内容的提问来源于stack exchange,提问作者FlagT
相关产品推荐
相关产品推荐

