【问题标题】:Find and delete duplicate edges in OrientDb在 OrientDb 中查找和删除重复的边
【发布时间】:2016-01-18 14:50:25
【问题描述】:

假设我们有 Vertex User 和 Edge FriendsWith。 FriendsWith 可以双向出入(通常是出入或在两个用户之间)。

重复是指从一个用户到另一个用户的外出或进入超过一次(外出和进入一起不被视为重复)

有没有办法找到重复的边缘并删除它们?

更新添加图片说明问题

谢谢。

【问题讨论】:

  • 一个JavaScript函数对你有用吗?
  • 当然,javascript 也会很好
  • 未来您可以为边添加唯一索引,因此两个顶点之间不允许有相同的标签边重复
  • 是的,这就是我打算做的,但发现重复

标签: orientdb orientdb-2.1


【解决方案1】:

这是我的 javascript 函数:

var g=orient.getGraph();
var C=g.command('sql','select from FriendsWith');
var arr = new Array(C.length);
var toRemove = new Array();

for(i=0;i<C.length;i++){
  var found = false;
  for (x = 0; x < i+1 && !found; x++) {
  if (arr[x] === C[i].getProperty("out").getId()+" "+C[i].getProperty("in").getId()) {
    found = true;
    toRemove.push(C[i].getId());
    }
  }
  arr[i] = C[i].getProperty("out").getId()+" "+C[i].getProperty("in").getId();
}

for(a=0;a<toRemove.length;a++){
  var C=g.command('sql','delete edge '+toRemove[a]);
}

希望对您有所帮助。 再见

【讨论】:

  • 感谢您的回复,但可能存在性能问题,因为我们有超过 600 000 个顶点和 800 000 条边。
【解决方案2】:

你可以试试这个功能

var g=orient.getGraph();
var friends=g.command("sql","select from FriendsWith");
var paths=[];
for(i=0;i<friends.length;i++){
    paths.push(friends[i]);
}
for(i=0;i<paths.length;i++){
    var myEdge=paths[i];
    var vIn=myEdge.getProperty("in").getId();
    var vOut=myEdge.getProperty("out").getId();
    for(j=0;j<paths.length;j++){
        if(i<j){
            var edge=paths[j];
            var vInCopy=edge.getProperty("in").getId();
            var vOutCopy=edge.getProperty("out").getId();
            if((vIn==vInCopy && vOut==vOutCopy) || (vIn==vOutCopy && vOut==vInCopy)){
                g.command("sql","delete edge FriendsWith where @rid="+edge.getId());
                paths.splice(j, 1);
                j--;
            } 
        }
    }
}

之前

【讨论】:

  • 似乎是我需要的,但有什么办法可以优化它,因为我已经有超过 800 000 条边
  • 你能把你的数据库发给我做一个测试或一个子集吗?
  • 超过2GB,部署需要2-3个小时。有一些真实数据
  • 我的目标是复制您的数据库,您是否在少数顶点上有很多重复边或重复边分布在许多顶点上?
  • 据我所知 - 重复的边分布在许多顶点上。
【解决方案3】:

我创建了一个小型数据库来尝试您的案例。这是我的代码:

create class User extends V
create class follows extends E

create property User.id integer
create property User.name String

create vertex User set id=1, name="Paul"
create vertex User set id=2, name="John"
create vertex User set id=3, name="Mark"
create vertex User set id=4, name="Robert"

create edge follows from (select from User where id=1) to (select from User where id=2)
create edge follows from (select from User where id=2) to (select from User where id=1)
create edge follows from (select from User where id=1) to (select from User where id=3)
create edge follows from (select from User where id=2) to (select from User where id=3)
create edge follows from (select from User where id=3) to (select from User where id=2)
create edge follows from (select from User where id=3) to (select from User where id=4)

图表:

然后我创建了一个简单的 Javascript 函数,一旦发现重复的边缘,它就会删除方向边缘。

输入:ridA(你开始@rid)

代码:

var g=orient.getGraph();
var outF=g.command('sql','select expand(out("follows")) from '+ridA);
var inF=g.command('sql','select expand(in("follows")) from '+ridA);
for(x=0;x<outF.length;x++){
  var ridOut=outF[x].getId();
  for(y=0;y<inF.length;y++){
    var ridIn=inF[y].getId();
    if(ridOut==ridIn){
      g.command('sql','delete edge follows from '+ridIn+' to '+ridA);
    }
  }
}

编辑:

例如,如果您尝试从顶点 #12:1 中删除重复的边,则在启动该函数后,两条“follow”方向边将被删除。

【讨论】:

  • 感谢您的回答,但这与我需要的略有不同。我需要为 ridOut 找到重复项(从 #12:0 到 #12:1 2 次或更多次)或 ridIn 而不是 ridOur == ridIn。
  • 嗨,你想从一个起始顶点删除多条边,对吗?
  • 只有可以在两个方向出现的重复项
  • 嗨,我在创建了从顶点 #12:1(总共 8 个边)到 4 个不同顶点的边“跟随”的 4 个副本后尝试了该函数,并且该函数删除了重复项。我使用了 ridOut == ridIn 因为如果它们指向同一个顶点,则意味着存在重复。一旦找到它,它只会删除“IN”方向,但“OUT”边缘仍然存在(但您也可以选择保留“OUT”方向)。总结一下,边的删除是从1(ridA)到N个顶点,不就是你要找的吗?
  • 我需要删除 ridOut、ridIn 或 (ridIn, ridOut) 出现超过 1 次的边
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-16
  • 2015-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多