源
发布于

聚合查询及相关语法——Neo4j

Neo4j是图形数据库,操作语法为CQL,CQL代表Cypher查询语言。 注意:有些语法需要APOC扩展包支持 多标签,多类型聚合查询操作示例:

    /**
     * @Description: findList,多标签查询指定关系节点
     * @param map: 
     * @return: java.util.Map
     * @Author: hsy
     * @Date: 2020/12/12
     */
    public Map findList(Map<String,Object> map){
        String cypher;      //Neo4j执行语句
        Map<String, Object> relation;       //返回结果集
        List<String> types = new ArrayList<>();     //关系类型集(type)
        if (map.containsKey("event_type") && null != map.get("event_type") && !"".equals(map.get("event_type"))){
            Map<String, Object> filter = new HashMap<>();
            filter.put("event_type",map.get("event_type"));
            List<Map<String, Object>> relationTypes = mongoDBService.findRelationTypes(filter);
            for (Map<String, Object> relationType:relationTypes){
                types.add(relationType.get("type").toString());
            }
        }
        types = addMark(types);
        if (map.containsKey("labels") && null != map.get("labels") && !"".equals(map.get("labels")) && map.get("labels") instanceof List){      //有节点标签条件(List)
            List<String> labels = (List<String>) map.get("labels");
            labels = addMark(labels);
            if (types.size()>0){        //有关系类别条件
                cypher = "match p=(n)-[r]-(m) where any(label in labels(n) where label in "+labels+") and type(r) in "+types+" return p";
                //cypher = "match p=(n)-[r]-(m) where any(label in labels(n) where label in "+labels+") and type(r) in "+types+" return n,r,m";
                relation = DatabaseUtil.deepQuery(cypher);
            }else {     //无关系类别条件
                cypher = "match p=(n)-[r]-(m) where any(label in labels(n) where label in "+labels+") return p";
                relation = DatabaseUtil.deepQuery(cypher);
            }
            if (!relation.containsKey("nodes") || null == relation.get("nodes") || "".equals(relation.get("nodes")) || (relation.get("nodes") instanceof Set && !(0<((Set) relation.get("nodes")).size()))){       //三元组查询结果为空,则返回节点
                cypher = "match (n) where any(label in labels(n) where label in "+labels+") return n";
                List<Map<String, Object>> nodes = DatabaseUtil.nodeToMap(cypher);
                relation.put("nodes",nodes);
                relation.put("relationships",new ArrayList<Map<String, Object>>());
            }
        }else if (map.containsKey("labels") && null != map.get("labels") && !"".equals(map.get("labels")) && map.get("labels") instanceof String){      //有节点标签条件(String)
            if (types.size()>0){        //有关系类别条件
                cypher = "match p=(n)-[r]-(m) where any(label in labels(n) where label = \'"+map.get("labels")+"\') and type(r) in "+types+" return p";
                relation = DatabaseUtil.deepQuery(cypher);
            }else {     //无关系类别条件
                cypher = "match p=(n)-[r]-(m) where any(label in labels(n) where label = \'"+map.get("labels")+"\') return p";
                relation = DatabaseUtil.deepQuery(cypher);
            }
            if (!relation.containsKey("nodes") || null == relation.get("nodes") || "".equals(relation.get("nodes")) || (relation.get("nodes") instanceof Set && !(0<((Set) relation.get("nodes")).size()))){       //三元组查询结果为空,则返回节点
                cypher = "match (n) where any(label in labels(n) where label = \'"+map.get("labels")+"\') return n";
                List<Map<String, Object>> nodes = DatabaseUtil.nodeToMap(cypher);
                relation.put("nodes",nodes);
                relation.put("relationships",new ArrayList<Map<String, Object>>());
            }
        }else {     //无节点标签条件
            if (types.size()>0){        //有关系类别条件
                cypher = "match p=(n)-[r]-(m) where type(r) in "+types+" return p";
                relation = DatabaseUtil.deepQuery(cypher);
            }else {     //无关系类别条件
                cypher = "match p=(n)-[r]-(m) return r limit 500";
                relation = DatabaseUtil.deepQuery(cypher);
            }
            if (!relation.containsKey("nodes") || null == relation.get("nodes") || "".equals(relation.get("nodes")) || (relation.get("nodes") instanceof Set && !(0<((Set) relation.get("nodes")).size()))){       //三元组查询结果为空,则返回节点
                cypher = "match (n) return n limit 50";
                List<Map<String, Object>> nodes = DatabaseUtil.nodeToMap(cypher);
                relation.put("nodes",nodes);
                relation.put("relationships",new ArrayList<Map<String, Object>>());
            }
        }
        return relation;
    }

    /**
     * @Description: deepQuery,深度查询返回三元组方法
     * @param string:   查询语句
     * @return: java.util.Map<java.lang.String,java.lang.Object>
     * @Author: hsy
     * @Date: 2020/12/12
     */
    public static Map<String, Object> deepQuery(String string){
        Set<Map<String, Object>> nodeList = new HashSet<>();
        Set<Map<String, Object>> relationshipList = new HashSet<>();
        Map<String, Object> relation = new HashMap<>();
        Result result = DatabaseUtil.neo4jExecute(string);
        Iterable<Map<String, Object>> it = result.queryResults();
        for (Map<String, Object> data : it){
            for (Map.Entry<String, Object> entry : data.entrySet()){
                Object object = entry.getValue();
                if (object instanceof InternalPath){
                    InternalPath IP = (InternalPath) object;
                    //节点
                    Iterable<Node> nodes = IP.nodes();
                    for (Node node : nodes){
                        Map<String, Object> asMap = node.asMap();
                        nodeList.add(setProperty(setBasePropertyNode(node),asMap));
                    }
                    //关系
                    Iterable<Relationship> relationships = IP.relationships();
                    for (Relationship relationship : relationships){
                        Map<String, Object> asMap = relationship.asMap();
                        relationshipList.add(setProperty(setBasePropertyRelation(relationship),asMap));
                    }
                }else if (object instanceof NodeModel){     //节点
                    NodeModel nodeModel = (NodeModel) object;
                    nodeList.add(setPropertyNodeModel(nodeModel));
                }else if (object instanceof RelationshipModel){     //关系
                    RelationshipModel relationshipModel = (RelationshipModel) object;
                    relationshipList.add(setPropertyRelationshipModel(relationshipModel));
                }
            }
        }
        relation.put("nodes",nodeList);
        relation.put("relationships",relationshipList);
        return relation;
    }
     /**
     * @Description: relationToMap,关系模型===》Map
     * @param string:
     * @return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     * @Author: hsy
     * @Date: 2020/12/12
     */
    public static List<Map<String, Object>> relationToMap(String string){
        Set<Map<String, Object>> relationships = new HashSet<>();
        Result resultRelations = DatabaseUtil.neo4jExecute(string);
        ArrayList<LinkedHashMap<String, ArrayList<RelationshipModel>>> listRelations = (ArrayList)resultRelations.queryResults();
        for (LinkedHashMap<String, ArrayList<RelationshipModel>> linkedHashMap:listRelations){
            for (ArrayList<RelationshipModel> value:linkedHashMap.values()){
                for (RelationshipModel relationshipModel:value){
                    relationships.add(DatabaseUtil.setPropertyRelationshipModel(relationshipModel));
                }
            }
        }
        return new ArrayList<>(relationships);
    }

    /**
     * @Description: nodeToMap,节点模型===》Map
     * @param string:
     * @return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     * @Author: hsy
     * @Date: 2020/12/12
     */
    public static List<Map<String, Object>> nodeToMap(String string){
        Set<Map<String, Object>> nodes = new HashSet<>();
        Result resultNode = DatabaseUtil.neo4jExecute(string);
        ArrayList<LinkedHashMap<String, NodeModel>> listNodes = (ArrayList)resultNode.queryResults();
        for (LinkedHashMap<String,NodeModel> linkedHashMap:listNodes){
            for (NodeModel value:linkedHashMap.values()){
                nodes.add(DatabaseUtil.setPropertyNodeModel(value));
            }
        }
        return new ArrayList<>(nodes);
    }

其他相关操作语法:

//创建节点
create (n:`地图`{name_chs:"中东",名称:"中东",经度:"48.00",纬度:"12.00"})

//模糊查询
MATCH (n:`舰艇`) where n.别名=~'.*埃塞克斯号.*' RETURN n

//查询与节点name为长沙有关的节点和关系
MATCH p=(n:`地图`{名称:'长沙市'})-[*1..1]-() return p limit 99

//创建关系(需要APOC包)
UNWIND {list} as row MATCH (startNode) WHERE startNode._id = row.start 
WITH row,startNode MATCH (endNode) WHERE endNode._id = row.end 
CALL apoc.create.relationship(startNode, row.type, row.props, endNode) yield rel 
RETURN count(*)

//根据name创建关系
UNWIND {list} as row MATCH (startNode) WHERE startNode.name = row.startNodeName 
WITH row,startNode MATCH (endNode) WHERE endNode.name = row.endNodeName 
Merge (startNode)-[rel:`TargetRelation`]->(endNode) SET rel += row.props

//根据id创建关系
UNWIND {rows} as row MATCH (startNode) WHERE ID(startNode) = row.startNodeId 
WITH row,startNode MATCH (endNode) WHERE ID(endNode) = row.endNodeId 
CREATE (startNode)-[rel:`TargetRelation`]->(endNode) SET rel += row.props

//创建指定关系
match(a),(b) where id(a)={0} and id(b)={1} 
create c= (a)-[r:TargetRelation{number:{2},startTarget:{3},relationType:{4},endTarget:{5},createTime:{6}}]->(b) return c

//节点多标签查询
match p=(n)-[r]-(m) where any(label in labels(n) where label in ['X1体系','X2体系']) return n

//关系多类型查询
match p=(n)-[r]-(m) where type(r) in ['指挥关系','备份关系'] return p

//节点标签,关系类型联合查询
match p=(n)-[r]-(m) where any(label in labels(n) where label in ['X1体系']) and type(r) in ['指挥关系','上报关系'] return p

社区版备份或者换库
//数据备份到文件
neo4j-admin  dump --database=graph.db --to=D:/Neo4j/neo4j-community-3.5.7/data/dump/graph.dump
//备份的数据文件导入
bin/neo4j-admin load --from=D:/Neo4j/neo4j-community-3.5.7/data/dump/graph.dump --database=graph.db --force

评论