|
@@ -923,3 +923,262 @@ RETURN p LIMIT 1
|
|
|
|
|
|
return false, nil, nil
|
|
|
}
|
|
|
+
|
|
|
+func CheckLegalRelationships5(session *nebula.Session, names []string, deep, stype int) (bool, []string, error) {
|
|
|
+ if len(names) < 2 {
|
|
|
+ return false, nil, fmt.Errorf("企业数量不足,至少需要两个")
|
|
|
+ }
|
|
|
+
|
|
|
+ var rawPaths []string
|
|
|
+ var rawNodeLists [][]string
|
|
|
+
|
|
|
+ for i := 0; i < len(names); i++ {
|
|
|
+ start := names[i]
|
|
|
+
|
|
|
+ targets := []string{}
|
|
|
+ for j := 0; j < len(names); j++ {
|
|
|
+ if i != j {
|
|
|
+ targets = append(targets, fmt.Sprintf(`"%s"`, names[j]))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ targetList := strings.Join(targets, ", ")
|
|
|
+
|
|
|
+ query := fmt.Sprintf(`
|
|
|
+USE %s;
|
|
|
+MATCH p=(a:Legal{name:"%s"})-[*1..%d]-(b:Legal)
|
|
|
+WHERE b.Legal.name IN [%s]
|
|
|
+RETURN p LIMIT 1
|
|
|
+`, Table_Space, start, deep, targetList)
|
|
|
+
|
|
|
+ resp, err := session.Execute(query)
|
|
|
+ if err != nil {
|
|
|
+ return false, nil, fmt.Errorf("查询失败: %w", err)
|
|
|
+ }
|
|
|
+ if !resp.IsSucceed() {
|
|
|
+ return false, nil, fmt.Errorf("查询执行失败: %s", resp.GetErrorMsg())
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp.GetRowSize() > 0 {
|
|
|
+ for _, row := range resp.GetRows() {
|
|
|
+ if len(row.Values) == 0 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ val := row.Values[0]
|
|
|
+ if !val.IsSetPVal() {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ path := val.GetPVal()
|
|
|
+ var builder strings.Builder
|
|
|
+ var nodeNames []string
|
|
|
+
|
|
|
+ curName := ""
|
|
|
+ srcVertex := path.Src
|
|
|
+ if srcVertex != nil && srcVertex.Vid != nil && srcVertex.Vid.IsSetSVal() {
|
|
|
+ vid := string(srcVertex.Vid.GetSVal())
|
|
|
+ lea, err := getLegalByVid(session, vid)
|
|
|
+ if err != nil {
|
|
|
+ log.Println("getLegalByVid err:", err, vid)
|
|
|
+ } else {
|
|
|
+ curName = lea.Name
|
|
|
+ }
|
|
|
+ }
|
|
|
+ builder.WriteString(curName)
|
|
|
+ nodeNames = append(nodeNames, curName)
|
|
|
+
|
|
|
+ for _, step := range path.Steps {
|
|
|
+ dstName := ""
|
|
|
+ if step.Dst != nil && step.Dst.Vid != nil && step.Dst.Vid.IsSetSVal() {
|
|
|
+ vid := string(step.Dst.Vid.GetSVal())
|
|
|
+ lea, err := getLegalByVid(session, vid)
|
|
|
+ if err != nil {
|
|
|
+ log.Println("getLegalByVid err:", err, vid)
|
|
|
+ } else {
|
|
|
+ if lea != nil && lea.Name != "" {
|
|
|
+ dstName = lea.Name
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if step.Type > 0 {
|
|
|
+ builder.WriteString(" → ")
|
|
|
+ } else if step.Type < 0 {
|
|
|
+ builder.WriteString(" ← ")
|
|
|
+ } else {
|
|
|
+ builder.WriteString(" - ")
|
|
|
+ }
|
|
|
+ builder.WriteString(dstName)
|
|
|
+ nodeNames = append(nodeNames, dstName)
|
|
|
+ }
|
|
|
+
|
|
|
+ rawPaths = append(rawPaths, builder.String())
|
|
|
+ rawNodeLists = append(rawNodeLists, nodeNames)
|
|
|
+
|
|
|
+ if stype == 0 {
|
|
|
+ return true, []string{builder.String()}, nil
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 去重 + 保留最长路径
|
|
|
+ uniqueMap := map[string]string{}
|
|
|
+ for i, nodes := range rawNodeLists {
|
|
|
+ pathStr := rawPaths[i]
|
|
|
+ key := generatePathKey(nodes)
|
|
|
+
|
|
|
+ shouldAdd := true
|
|
|
+ for k, _ := range uniqueMap {
|
|
|
+ existingNodes := strings.Split(k, "|")
|
|
|
+ if isSubPath(nodes, existingNodes) || isSubPath(reverseSlice(nodes), existingNodes) {
|
|
|
+ shouldAdd = false
|
|
|
+ break
|
|
|
+ }
|
|
|
+ if isSubPath(existingNodes, nodes) {
|
|
|
+ delete(uniqueMap, k)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if shouldAdd {
|
|
|
+ uniqueMap[key] = pathStr
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var finalPaths []string
|
|
|
+ for _, v := range uniqueMap {
|
|
|
+ finalPaths = append(finalPaths, v)
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(finalPaths) > 0 {
|
|
|
+ return true, finalPaths, nil
|
|
|
+ }
|
|
|
+ return false, nil, nil
|
|
|
+}
|
|
|
+
|
|
|
+// CheckLegalRelationships CheckLegalRelationships
|
|
|
+func (c *NebulaClient) CheckLegalRelationships(names []string, deep, stype int) (bool, []string, error) {
|
|
|
+ if len(names) < 2 {
|
|
|
+ return false, nil, fmt.Errorf("企业数量不足,至少需要两个")
|
|
|
+ }
|
|
|
+
|
|
|
+ var rawPaths []string
|
|
|
+ var rawNodeLists [][]string
|
|
|
+
|
|
|
+ for i := 0; i < len(names); i++ {
|
|
|
+ start := names[i]
|
|
|
+
|
|
|
+ targets := []string{}
|
|
|
+ for j := 0; j < len(names); j++ {
|
|
|
+ if i != j {
|
|
|
+ targets = append(targets, fmt.Sprintf(`"%s"`, names[j]))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ targetList := strings.Join(targets, ", ")
|
|
|
+
|
|
|
+ query := fmt.Sprintf(`
|
|
|
+USE %s;
|
|
|
+MATCH p=(a:Legal{name:"%s"})-[*1..%d]-(b:Legal)
|
|
|
+WHERE b.Legal.name IN [%s]
|
|
|
+RETURN p LIMIT 1
|
|
|
+`, Table_Space, start, deep, targetList)
|
|
|
+
|
|
|
+ resp, err := c.ExecuteWithReconnect(query)
|
|
|
+ if err != nil {
|
|
|
+ return false, nil, fmt.Errorf("查询失败: %w", err)
|
|
|
+ }
|
|
|
+ if !resp.IsSucceed() {
|
|
|
+ return false, nil, fmt.Errorf("执行失败: %s", resp.GetErrorMsg())
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp.GetRowSize() > 0 {
|
|
|
+ for _, row := range resp.GetRows() {
|
|
|
+ if len(row.Values) == 0 || !row.Values[0].IsSetPVal() {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ path := row.Values[0].GetPVal()
|
|
|
+ var builder strings.Builder
|
|
|
+ var nodeNames []string
|
|
|
+
|
|
|
+ // 起点
|
|
|
+ src := path.Src
|
|
|
+ curName := ""
|
|
|
+ if src != nil && src.Vid != nil && src.Vid.IsSetSVal() {
|
|
|
+ vid := string(src.Vid.GetSVal())
|
|
|
+ lea, err := getLegalByVid(c.session, vid)
|
|
|
+ if err != nil {
|
|
|
+ log.Println("getLegalByVid err:", err, vid)
|
|
|
+ } else if lea != nil && lea.Name != "" {
|
|
|
+ curName = lea.Name
|
|
|
+ }
|
|
|
+ }
|
|
|
+ builder.WriteString(curName)
|
|
|
+ nodeNames = append(nodeNames, curName)
|
|
|
+
|
|
|
+ // 步长处理
|
|
|
+ for _, step := range path.Steps {
|
|
|
+ dstName := ""
|
|
|
+ if step.Dst != nil && step.Dst.Vid != nil && step.Dst.Vid.IsSetSVal() {
|
|
|
+ vid := string(step.Dst.Vid.GetSVal())
|
|
|
+ lea, err := getLegalByVid(c.session, vid)
|
|
|
+ if err != nil {
|
|
|
+ log.Println("getLegalByVid err:", err, vid)
|
|
|
+ } else if lea != nil && lea.Name != "" {
|
|
|
+ dstName = lea.Name
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if step.Type > 0 {
|
|
|
+ builder.WriteString(" → ")
|
|
|
+ } else if step.Type < 0 {
|
|
|
+ builder.WriteString(" ← ")
|
|
|
+ } else {
|
|
|
+ builder.WriteString(" - ")
|
|
|
+ }
|
|
|
+ builder.WriteString(dstName)
|
|
|
+ nodeNames = append(nodeNames, dstName)
|
|
|
+ }
|
|
|
+
|
|
|
+ rawPaths = append(rawPaths, builder.String())
|
|
|
+ rawNodeLists = append(rawNodeLists, nodeNames)
|
|
|
+
|
|
|
+ if stype == 0 {
|
|
|
+ return true, []string{builder.String()}, nil
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 去重 + 最长路径保留
|
|
|
+ uniqueMap := map[string]string{}
|
|
|
+ for i, nodes := range rawNodeLists {
|
|
|
+ pathStr := rawPaths[i]
|
|
|
+ key := generatePathKey(nodes)
|
|
|
+
|
|
|
+ shouldAdd := true
|
|
|
+ for k := range uniqueMap {
|
|
|
+ existingNodes := strings.Split(k, "|")
|
|
|
+ if isSubPath(nodes, existingNodes) || isSubPath(reverseSlice(nodes), existingNodes) {
|
|
|
+ shouldAdd = false
|
|
|
+ break
|
|
|
+ }
|
|
|
+ if isSubPath(existingNodes, nodes) {
|
|
|
+ delete(uniqueMap, k)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if shouldAdd {
|
|
|
+ uniqueMap[key] = pathStr
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var finalPaths []string
|
|
|
+ for _, v := range uniqueMap {
|
|
|
+ finalPaths = append(finalPaths, v)
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(finalPaths) > 0 {
|
|
|
+ return true, finalPaths, nil
|
|
|
+ }
|
|
|
+ return false, nil, nil
|
|
|
+}
|