记图数据库neo4j使用过程遇到的问题

1. 事物问题
我们学习的neo4j的时候,一般都是对neo4j数据库直接进行操作,而实际生产过程中,neo4j的数据则来源于很多地方,比如我现在用到的mysql、redis、clickhouse等等。
而看过我之前博客的同学应该知道,我是基于spring jpa对neo4j数据库进行操作的,spring jpa已经对事物进行了默认封装,而我们此时用到了多数据源,那么势必会存在事物切换的问题
比如我先对mysql数据库进行操作,再对neo4j进行操作,那么这两步操作可以使用一个事物吗?显然是不可能的。那么,我们如何解决这种问题呢?
解决方案:
1. 配置mysql的数据源在这里插入图片描述
2. 配置mysql数据源的默认事物 在这里插入图片描述
3. 配置neo4j的Session对象(session对象类似于mysql创建的jdbc连接对象,拿到对象可以直接对数据库进行操作)
在这里插入图片描述
4. 先操作mysql查询,再进行保存neo4j操作
在这里插入图片描述在这里插入图片描述

2. 入库效率问题
使用java对neo4j数据库进行直接插入的效率非常底下,经测试,5万个节点插入,耗时半个小时以上,即便采用事物批量提交也是一样,且java bolt存在一个管道buff的大小问题,一次提交的数据不能超过buff最大长度。
解决办法:
1. 将需要插入的节点去重
2. 将去重的节点数据写入本地磁盘,已csv的格式保存数据
3. 通过执行LOAD CSV命令导入磁盘中的csv文件,设置事物提交条数
导入节点:session.run(“using periodic commit 100 LOAD CSV WITH HEADERS FROM “file:///” + nodeFileName + “.csv” AS line merge (a:BasicNode {name:line.name, value: line.value}) return a”);
导入关系:session.run("using periodic commit 10 LOAD CSV WITH HEADERS FROM “file:///” + relationshipFileName + “.csv” AS line " + “match (from:BasicNode{name:line.name}),(to:BasicNode{name:line.value}) merge (from) - [:relation{type:line.type}] -> (to)”);

3. 导入CVS文件的问题
neo4j在导入数据文件的时候,默认是去neo4j安装路径下的import文件夹下读取要导入的数据文件,如果在生成文件的时候,路径不对,就会导致导入失败。
解决办法:
1. 在application.properties文件中,写入neo4j的安装路径
在这里插入图片描述
2. 在代码中注入安装路径
在这里插入图片描述

或者修改neo4j的配置文件
#下面的意思是只能从import目录下导入,可以改变这个地址,或者去掉,去掉的话可以从任意位置导入
dbms.directories.import=import

4. spring jpa复杂查询返回对象的问题
spring jpa的出现,大大减少了程序猿在对数据库进行操作时的工作量,减少了很多不必要写的代码,而spring jpa并不是什么新技术,它只是基于ORM框架所开发的一种规约、规范,只能操作一些比较常规且简单的数据库操作,虽然大部分情况下,这些规约能够满足我们日常的使用。
而neo4j因为关系和节点、属性之间的复杂关系,往往在使用spring jpa的数据,会因为返回参数而大伤脑筋。那么,如果复杂的查询及结果如何去做?
解决方案:
1. 配置neo4j的session对象
在这里插入图片描述
2. 通过指定节点数据,查询节点的关系

@Autowired
	private Session session;

	/**
	 * 根据开始节点查询关联关系节点,可指定结束节点查询
	 * @param startNode 开始节点名称
	 * @param endNode 结束节点名称
	 * @return
	 */
	public Map<String, List<Map<String, Object>>> findByNameAndRelation(String startNode, String endNode) {
		String cypherSql = String.format("match p = ((a:BasicNode {name:\"%s\"}) - [*..5] - ()) return p limit 1000", startNode);
		if (StringUtils.isNotEmpty(endNode)) {
			cypherSql = String.format("match (a:Sheeps {name:\"%s\"}) - [b] -> (c:Sheeps {name:\"%s\"}) return a,b,c limit 1000", startNode, endNode);
		}
		Result result = session.run(cypherSql);
		Map<String, List<Map<String, Object>>> resultMap = new HashMap<String, List<Map<String, Object>>>();
		List<Map<String, Object>> nodesList = new ArrayList<Map<String, Object>>();
		List<Map<String, Object>> relationshipList = new ArrayList<Map<String, Object>>();
		Map<Long, String> nodeIds = new HashMap<Long, String>(); // 保存id,用于去重
		Map<Long, String> relationIds = new HashMap<Long, String>(); // 保存id,用于去重
		while (result.hasNext()) {
			Record record = result.next();
			List<Value> values = record.values();
			for (Value value : values) {
				if ("NODE".equals(value.type().name())) {
					Node node = value.asNode();
					if (!nodeIds.containsKey(node.id())) {
						Map<String, Object> map = setMap(node);
						nodesList.add(map);
						nodeIds.put(node.id(), "");
					}
				} else if ("RELATIONSHIP".equals(value.type().name())) {
					Relationship relationship = value.asRelationship();
					Map<String, Object> map = setMap(relationship);
					relationshipList.add(map);
				} else if ("PATH".equals(value.type().name())) {
					Path path = value.asPath();
					Iterable<Node> nodes = path.nodes();
					for (Node node : nodes) {
						if (!nodeIds.containsKey(node.id())) {
							Map<String, Object> map = setMap(node);
							nodesList.add(map);
							nodeIds.put(node.id(), "");
						}
					}
					Iterable<Relationship> relationships = path.relationships();
					for (Relationship relationship : relationships) {
						if (!relationIds.containsKey(relationship.id())) {
							Map<String, Object> map = setMap(relationship);
							relationshipList.add(map);
							relationIds.put(relationship.id(), "");
						}
					}
				}
			}
		}
		resultMap.put("relationship", relationshipList);
		resultMap.put("nodes", nodesList);
		relationIds.clear();
		relationIds = null;
		nodeIds.clear();
		nodeIds = null;
		return resultMap;
	}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值