基于neo4j-java-driver驱动访问图库封装rest-api风格的数据

分享一个neo4j数据封装类,这个类封装的JSON数据与neo4j的rest-api返回的数据格式类似。

  1. 负责区分不同查询
    /**
    * @param cypher@return
    * @Description: TODO(跳过条件添加直接使用CYPHER查询 - 默认返回节点或者关系的所有属性字段)
    */
   @Override
   public JSONObject execute(String cypher, CRUD crudType) {
       // 禁止某些危险查询
       if (cypher.contains("DELETE") || cypher.contains("REMOVE") ||
               cypher.contains("delete") || cypher.contains("remove")) {
           this.logger.info("The cypher statement forbidden execution!", new IllegalAccessException());
           return null;
       }
       long startMill = System.currentTimeMillis();
       JSONArray queryResultList = new JSONArray();
       Condition condition = new Condition();
       condition.setStatement(cypher, this.contents);
       queryResultList.add(Result.message(chooseSendCypherWay(condition, crudType)));

       JSONObject result = Result.statistics(queryResultList);
       // 统计所有请求的耗时,以及每个请求的平均耗时
       long stopMill = System.currentTimeMillis();
       result.put("consume", Result.statisticsConsume(startMill, stopMill, queryResultList.size(), this.logger));

       if (ResultDataContents.D3_GRAPH.equals(this.contents) && !CRUD.RETRIEVE_PROPERTIES.equals(crudType)) {
           result = JSONTool.packD3Json(result);
       }
       if (this.DEBUG) {
           this.logger.info("Debug condition:" + condition.toString());
       }
       return result;
   }

   /**
    * @param
    * @return
    * @Description: TODO(使用REST - API或者JAVA - DRIVER执行请求)
    */
   public JSONObject chooseSendCypherWay(Condition condition, CRUD crudType) {
       if (this.DEBUG) {
           this.logger.info("Debug condition:" + condition.toString());
       }
       if (AccessOccurs.RESTFUL_API.equals(this.accessOccurs)) {
           return JSONObject.parseObject(this.request.httpPost(NeoUrl.DB_DATA_TRANSACTION_COMMIT.getSymbolValue(), condition.toString()));
       } else if (AccessOccurs.JAVA_DRIVER.equals(this.accessOccurs)) {
           if (CRUD.RETRIEVE.equals(crudType)) {
               return Neo4jDriver.searcher(this.driver, condition.getStatement(condition.toString()));
           } else if (CRUD.MERGE_CSV.equals(crudType)) {
               return Neo4jDriver.composerAutoCommit(this.driver, condition.getStatement(condition.toString()));
           } else if (CRUD.RETRIEVE_PROPERTIES.equals(crudType)) {
               return Neo4jDriver.rowProperties(this.driver, condition.getStatement(condition.toString()));
           } else if (CRUD.MERGE_RETURN_NODE_ID.equals(crudType)) {
               return Neo4jDriver.composerReturnNodeId(this.driver, condition.getStatement(condition.toString()));
           } else {
               return Neo4jDriver.composer(this.driver, condition.getStatement(condition.toString()));
           }
       }
       return new JSONObject();
   }
  1. Neo4jDriver负责数据封装
import casia.isi.neo4j.common.CRUD;
import casia.isi.neo4j.common.TimeUnit;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.log4j.Logger;
import org.neo4j.driver.internal.value.*;
import org.neo4j.driver.v1.*;
import org.neo4j.driver.v1.types.Node;
import org.neo4j.driver.v1.types.Path;
import org.neo4j.driver.v1.types.Relationship;
import org.neo4j.driver.v1.util.Pair;

import java.util.List;
import java.util.Map;

/**
 * @author YanchaoMa [email protected]
 * @PACKAGE_NAME: casia.isi.neo4j.driver
 * @Description: TODO(NEO4J_JAVA_DRIVER驱动)
 * @date 2019/7/13 19:50
 */
public class Neo4jDriver {

    /**
     * JAVA_DRIVER返回的数据格式统一按照D3_GRAPH格式返回
     **/

    private final static Logger logger = org.apache.log4j.Logger.getLogger(Neo4jDriver.class);

    /**
     * @param driver:传入NEO4J_JAVA驱动
     * @param statement:cypher
     * @return
     * @Description: TODO(构图导入等操作访问)
     */
    public synchronized static JSONObject composer(Driver driver, String statement) {
        long startMill = System.currentTimeMillis();

        boolean flag = false;
        // RETRY FAILURE QUERY
        while (!flag) {
            try (Session session = driver.session()) {
                try (Transaction tx = session.beginTransaction()) {
                    tx.run(statement);
                    tx.success();  // Mark this write as successful.
                    flag = true;
                }
            } catch (Exception e) {
                logger.info("Retrying query " + statement + "\r\n");
                e.printStackTrace();
            }
        }
        long stopMill = System.currentTimeMillis();
        long consume = (stopMill - startMill) / Integer.parseInt(String.valueOf(TimeUnit.MILL_SECOND_CV.getSymbolValue()));
        if (consume != 0) {
            logger.info("Neo4j driver composer success!consume:" + consume + "s");
        } else {
            logger.info("Neo4j driver composer success!consume:" + (stopMill - startMill) + "mills");
        }
        return new JSONObject();
    }

    /**
     * @param driver:传入NEO4J_JAVA驱动
     * @param statement:cypher
     * @return
     * @Description: TODO(构图导入等操作访问)
     */
    public synchronized static JSONObject composerReturnNodeId(Driver driver, String statement) {
        JSONObject resultMessage = new JSONObject();
        long startMill = System.currentTimeMillis();
        try (Session session = driver.session()) {
            try (Transaction tx = session.beginTransaction()) {
                StatementResult result = tx.run(statement);
                while (result.hasNext()) {
                    Record record = result.next();
                    Map<String, Object> map = record.asMap();
                    JSONObject object = JSONObject.parseObject(JSON.toJSONString(map));
                    resultMessage.putAll(object);
                }
                tx.success();  // Mark this write as successful.
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        long stopMill = System.currentTimeMillis();
        long consume = (stopMill - startMill) / Integer.parseInt(String.valueOf(TimeUnit.MILL_SECOND_CV.getSymbolValue()));
        if (consume != 0) {
            logger.info("Neo4j merge composer success!consume:" + consume + "s");
        } else {
            logger.info("Neo4j merge composer success!consume:" + (stopMill - startMill) + "mills");
        }
        return resultMessage;
    }

    /**
     * @param driver:传入NEO4J_JAVA驱动
     * @param statement:cypher
     * @return
     * @Description: TODO(构图导入等操作访问)
     */
    public synchronized static JSONObject composerAutoCommit(Driver driver, String statement) {
        long startMill = System.currentTimeMillis();
        try (Session session = driver.session()) {
            /**
             * AUTO COMMIT TRANSACTION
             * **/
            session.run(statement);
        } catch (Exception e) {
            e.printStackTrace();
        }
        long stopMill = System.currentTimeMillis();
        long consume = (stopMill - startMill) / Integer.parseInt(String.valueOf(TimeUnit.MILL_SECOND_CV.getSymbolValue()));
        logger.info("Neo4j driver composer auto commit success!consume:" + consume + "s");
        return new JSONObject();
    }

    public static JSONObject rowProperties(Driver driver, String cypher) {
        JSONObject resultObject = new JSONObject();
        JSONArray resultArray = new JSONArray();
        try (Session session = driver.session()) {
            StatementResult result = session.run(cypher);
            while (result.hasNext()) {
                Record record = result.next();
                Map<String, Object> map = record.asMap();
                JSONObject object = transferObject(map);
                resultArray.add(object);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        resultObject.put(CRUD.RETRIEVE_PROPERTIES.getSymbolValue(), resultArray);
        return resultObject;
    }

    private static JSONObject transferObject(Map<String, Object> map) {
        JSONObject object = new JSONObject();
        for (String key : map.keySet()) {
            Object value = map.get(key);
            if (value instanceof Relationship) {
                Relationship relationship = (Relationship) value;
                JSONObject relation = packRelation(relationship);
                object.put(key, relation);
            } else if (value instanceof List) {
                JSONArray array = transferArray(value);
                object.put(key, array);
            } else {
                object.put(key, value);
            }
        }
        return object;
    }

    private static JSONArray transferArray(Object value) {
        List<Object> list = (List<Object>) value;
        JSONArray array = new JSONArray();
        for (Object object : list) {
            if (object instanceof Relationship) {
                JSONObject relation = packRelation((Relationship) object);
                array.add(relation);
            }else if (object instanceof  Node){
                JSONObject relation = packNode((Node) object);
                array.add(relation);
            }else {
                array.add(object);
            }
        }
        return array;
    }

    /**
     * @param driver:传入NEO4J_JAVA驱动
     * @param statement:cypher
     * @return
     * @Description: TODO(检索)
     */
    public static JSONObject searcher(Driver driver, String statement) {

        long startMill = System.currentTimeMillis();

        JSONObject results = new JSONObject();
        JSONArray resultArray = new JSONArray();
        JSONObject arrayObject = new JSONObject();

        JSONArray columns = new JSONArray();
        JSONArray data = new JSONArray();
        JSONObject dataObject = new JSONObject();
        JSONObject graph = new JSONObject();

        JSONArray relationships = new JSONArray();
        JSONArray nodes = new JSONArray();
        JSONArray properties = new JSONArray();

        try (Session session = driver.session()) {
            // Auto-commit transactions are a quick and easy way to wrap a read.

            StatementResult result = session.run(statement);
            // Each Cypher execution returns a stream of records.
            while (result.hasNext()) {
                Record record = result.next();
                // Values can be extracted from a record by index or name.

                List<Pair<String, Value>> list = record.fields();

                JSONObject propertiesPack = new JSONObject();
                for (int i = 0; i < list.size(); i++) {
                    Pair<String, Value> stringValuePair = list.get(i);
                    if (!columns.contains(stringValuePair.key())) {
                        columns.add(stringValuePair.key());
                    }
                    Value value = stringValuePair.value();
                    if (value instanceof NodeValue) {
                        JSONObject objectNode = packNode(value.asNode());
                        if (!nodes.contains(objectNode)) nodes.add(objectNode);
                    } else if (value instanceof PathValue) {

                        JSONArray objectNodes = packNodeByPath(value.asPath());
                        objectNodes.forEach(node -> {
                            JSONObject nodeObj = (JSONObject) node;
                            if (!nodes.contains(nodeObj)) nodes.add(nodeObj);
                        });

                        JSONArray objectRelas = packRelations(value.asPath());
                        objectRelas.forEach(relation -> {
                            JSONObject relationObj = (JSONObject) relation;
                            if (!relationships.contains(relationObj)) relationships.add(relationObj);
                        });
                    } else {
                        propertiesPack.putAll(packStringValuePair(stringValuePair));
                    }
                }
                if (!propertiesPack.isEmpty()) properties.add(propertiesPack);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        graph.put("relationships", relationships);
        graph.put("nodes", nodes);
        graph.put("properties", properties);
        dataObject.put("graph", graph);
        data.add(dataObject);
        arrayObject.put("data", data);
        arrayObject.put("columns", columns);
        resultArray.add(arrayObject);
        results.put("results", resultArray);
        results.put("totalNodeSize", nodes.size());
        results.put("totalRelationSize", relationships.size());

        long stopMill = System.currentTimeMillis();
        long consume = (stopMill - startMill) / Integer.parseInt(String.valueOf(TimeUnit.MILL_SECOND_CV.getSymbolValue()));
        logger.info("Neo4j driver searcher success!consume:" + consume + "s");
        return results;
    }

    private static JSONObject packStringValuePair(Pair<String, Value> stringValuePair) {
        String key = stringValuePair.key();
        Value value = stringValuePair.value();
        JSONObject object = new JSONObject();
        if (value instanceof BooleanValue) {
            object.put(key, value.asBoolean());
        } else if (value instanceof FloatValue) {
            object.put(key, value.asFloat());
        } else if (value instanceof IntegerValue) {
            // object.put(key, value.asInt());
            object.put(key, value.asLong());
        } else if (value instanceof ListValue) {
            object.put(key, value.asList());
        } else {
            object.put(key, value.asString());
        }
        return object;
    }

    private static JSONArray packRelations(Path path) {
        JSONArray arrayRelations = new JSONArray();
        for (Relationship relationship : path.relationships()) {
            arrayRelations.add(packRelation(relationship));
        }
        return arrayRelations;
    }

    private static JSONObject packRelation(Relationship relationship) {
        JSONObject currentRelation = new JSONObject();
        currentRelation.put("startNode", relationship.startNodeId());
        currentRelation.put("id", relationship.id());
        currentRelation.put("type", relationship.type());
        currentRelation.put("endNode", relationship.endNodeId());
        currentRelation.put("properties", JSONObject.parseObject(JSON.toJSONString(relationship.asMap())));
        return currentRelation;
    }

    private static JSONArray packNodeByPath(Path path) {
        JSONArray pathNodes = new JSONArray();
        for (Node node : path.nodes()) {
            pathNodes.add(packNode(node));
        }
        return pathNodes;
    }

    private static JSONObject packNode(Node node) {
        JSONObject currentNode = new JSONObject();
        currentNode.put("id", node.id());
        currentNode.put("properties", JSONObject.parseObject(JSON.toJSONString(node.asMap())));
        currentNode.put("labels", JSONArray.parseArray(JSON.toJSONString(node.labels())));
        return currentNode;
    }

}
  1. 样例数据格式
{"totalNodeSize":3,"totalRelationSize":2,"consume":"Total consume 0s,average consume 0s/request","failed":0,"totalQuery":1,"message":true,"results":[{"data":[{"graph":{"relationships":[{"startNode":161,"id":40122,"type":"发帖","endNode":34650,"properties":{"relationType":"发帖","pub_time_mills":1573569457000,"update_time_mills":1582283028366}},{"startNode":497,"id":40123,"type":"转发","endNode":34650,"properties":{"pub_time_mills":1573575391000,"update_time_mills":1582283028366}}],"nodes":[{"id":161,"properties":{"_unique_uuid":"0cd911cea1f97c6ef610721ac81adc61","name":"Denise Ho (HOCC)","nameNodeSpace":"Denise Ho (HOCC)","update_time_mills":1582283028366},"labels":["TwitterID"]},{"id":34650,"properties":{"_unique_uuid":"e6c41e85e33ee38d826fcf2c0ba2d8b9","nameNodeSpace":"转推了","name":"转推了","update_time_mills":1582283028366},"labels":["Twitter发帖"]},{"id":497,"properties":{"_unique_uuid":"6fa25ec0b043445c144e44e33c57121d","loadRecommendEnginePathSize":6,"nameNodeSpace":"Wenli9187","name":"Wenli9187","update_time_mills":1582283148428},"labels":["TwitterID"]}],"properties":[]}}],"columns":["p"]}],"successful":1}
发布了173 篇原创文章 · 获赞 113 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/superman_xxx/article/details/104826962