apache / incubator-hugegraph-toolchain

HugeGraph toolchain - include a series useful graph modules
https://hugegraph.apache.org/
Apache License 2.0
88 stars 92 forks source link

相同ID的数据会被覆盖,并且 edgeLable 中的 sourceType 和 targetType 与实际建立的边数据类型不匹配 #212

Closed Ckuangf closed 3 years ago

Ckuangf commented 3 years ago

vertex-A.txt(共有38个顶点,对应的lable是loadTable) image vertex-B.txt(共有1206个顶点,对应的lable是loadTableColumn) image image schema.groovy image edge.json image

结果:

  1. 通过file的方式导入数据的时候,如果出现id相同的数据,后导入的数据会覆盖之前的 由于vertext-A.txt中的数据和vertext-B.txt中的数据有id重复,而导入的数据都是通过id作为主键,此时导入完成之后,相同id的vertext-B中的数据会覆盖A中的数据 image image image

  2. edgeLable中的sourceType和targetType与实际建立的边数据类型不匹配 创建的edgeLable为schema.edgeLabel("loadTable2Column").sourceLabel("loadTable") .targetLabel("loadTableColumn").ifNotExist().create(); 但是生成的边是loadTableColumn-loadTableColumn,个人猜测是因为后续的B的数据因为顶点id相同将原先的A的数据进行了替换 image

imbajin commented 3 years ago

首先, 你的核心覆盖问题, 是正常的现象, 你两条数据同样的 ID, 如果后者不覆盖前者, 那就应该采用更新或转换不同 id 的方式去设置, 不然数据库主键唯一, 自然不会允许有 key 重复的数据. (就像你没法在一个文件夹下命名两个一样的文件名)

重复的数据, 根据你自己业务场景可以有两个选择:

  1. 点边数据, 如果你期望有 "累加 / 合并交集 / 并集 / 追加 / 取大 / 取小 / 保留非空" 等策略, 导入数据时带上 update_strategies (参考文档, 可对每个属性设置)
  2. 如果是边数据, 比如两个人的通话记录, 你希望都存储下来, 那么设置比如通话时间为 sortkey, 这样可以保证多条数据同时存在.

至于你说的另一个问题, 没太清晰, 建议你拿两条具体的数据举例, 期望是什么, 实际是什么. 然后你的id 如果无法保证唯一, 或者说同一个id可能有多个不同用途, 可以使用 主键模式 去自动区分 id, 参考 issue

Ckuangf commented 3 years ago

首先, 你的核心覆盖问题, 是正常的现象, 你两条数据同样的 ID, 如果后者不覆盖前者, 那就应该采用更新或转换不同 id 的方式去设置, 不然数据库主键唯一, 自然不会允许有 key 重复的数据. (就像你没法在一个文件夹下命名两个一样的文件名)

重复的数据, 根据你自己业务场景可以有两个选择:

  1. 点边数据, 如果你期望有 "累加 / 合并交集 / 并集 / 追加 / 取大 / 取小 / 保留非空" 等策略, 导入数据时带上 update_strategies (参考文档, 可对每个属性设置)
  2. 如果是边数据, 比如两个人的通话记录, 你希望都存储下来, 那么设置比如通话时间为 sortkey, 这样可以保证多条数据同时存在.

至于你说的另一个问题, 没太清晰, 建议你拿两条具体的数据举例, 期望是什么, 实际是什么. 然后你的id 如果无法保证唯一, 或者说同一个id可能有多个不同用途, 可以使用 主键模式 去自动区分 id, 参考 issue

有关的覆盖问题这块我有去看过一下hugegraph-server顶点和边建立更新的过程,对于id唯一,然后导致更新的情况,是否可以考虑这个id在某个label中唯一,在不同lable是可以重复的。 另外一个问题可能是我描述的不太准确,这里的过程应该是我建立了一个sourceType为loaderTable,targetType是loaderTableColumn的edgeLable loadTable2Column,但是由于id覆盖的问题,导致我最后生成的数据 edge是 loadTable2Column,而两端的顶点都是loaderTableColumn,所以这里是出现了由于覆盖修改,导致我边两端的顶点类型没有受到edgeLable定义的约束

imbajin commented 3 years ago

你说的就是主键 ID 模式(也是大部分场景推荐的模式), 在发你的那个参考 issue 里有具体举例说明, 设置方式参考文档即可.

第二个主要是需要列出具体的 fromVID + toVID + edgeID , 用具体例子来说对着说, 才是最直观不容易有误解的, 当然如果你已经知道原因了就没事了.

Ckuangf commented 3 years ago

你说的就是主键 ID 模式(也是大部分场景推荐的模式), 在发你的那个参考 issue 里有具体举例说明, 设置方式参考文档即可.

第二个主要是需要列出具体的 fromVID + toVID + edgeID , 用具体例子来说对着说, 才是最直观不容易有误解的, 当然如果你已经知道原因了就没事了. 这个是我截图的第二个问题产生的数据 这个是fromVID为2的类型为loadTable的顶点数据 image 这个toVID为49 和 55类型为loadTableColumn的顶点数据 image 我定义的edgeLable是 image

正常情况下,如果没有出现id覆盖的时候,建立的关系应该是 id:2 lable:loadTable -> id:49 lable:loadTableColumn id:2 lable:loadTable -> id:55 lable:loadTableColumn 但是由于出现了id覆盖的情况 id为2 类型为loadTable的顶点被覆盖成了id为2 类型为loadTableColumn的顶点。此时建立的关系也变成了下面这种 image 变成了loadTableColumn -> loadTableColumn的 关系 对于这种情况,是否有可以强制更新失败的操作或者异常提醒呢

Linary commented 3 years ago

@Ckuangf 确实是因为Id覆盖导致出现了上面的现象。

避免Id覆盖有两种方式:

  1. 使用PrimaryKey的Id策略,这样不同label的顶点即使有相同的字面id也不会覆盖;
  2. 如果你硬要用Customize的Id策略,可以开启服务端的参数vertex.check_customized_id_exist=true,当碰到不同label的顶点的相同id时会抛出错误。但是因为要检查,所以导入速度会变慢。
Ckuangf commented 3 years ago

@Ckuangf 确实是因为Id覆盖导致出现了上面的现象。

避免Id覆盖有两种方式:

  1. 使用PrimaryKey的Id策略,这样不同label的顶点即使有相同的字面id也不会覆盖;
  2. 如果你硬要用Customize的Id策略,可以开启服务端的参数vertex.check_customized_id_exist=true,当碰到不同label的顶点的相同id时会抛出错误。但是因为要检查,所以导入速度会变慢。

嗯嗯 我去试下,谢谢大佬