【问题标题】:Finding the most common vertex connected to neighbors by a certain edge and using this, and edge information, to perform calculations找到通过某个边缘连接到邻居的最常见的顶点,并使用此和边缘信息来执行计算
【发布时间】:2015-12-03 14:12:54
【问题描述】:

我想根据他们关注的人来确定一个人可能来自哪里,并将这个国家与大致的纬度和经度放在一起。我有两种类型的节点:用户(包含名称,可能包含纬度和经度)和国家(包含名称)。我还有两种类型的边缘:Follow 和 LivesIn(包含 lat 和 lng)。

目前,Account 和 LivesIn 边缘都包含 lat 和 lng,因为我不完全确定哪里会更好,但目前我倾向于将它放在边缘。

下面是一个有五个用户的示例网络。其中三个我知道他们来自哪里。现在我想有根据地猜测爱丽丝来自哪里:

  1. 爱丽丝关注了四个用户
  2. 这四位用户中有两位来自德国,一位来自比利时,一位不知名
  3. 我们可以假设 Alice 来自德国
  4. 德国用户的平均 lat 和 lng 为 (51.165691+51.115691)/2 和 (10.451526+10.481526)/2
  5. 我们可以假设 Alice 在 (51.140691; 10.466526) 附近的某个地方

.

CREATE CLASS Account EXTENDS V
CREATE PROPERTY Account.name string
CREATE PROPERTY Account.lat double
CREATE PROPERTY Account.lng double

CREATE CLASS Country EXTENDS V
CREATE PROPERTY Country.countryname string

CREATE CLASS LivesIn EXTENDS E
CREATE PROPERTY LivesIn.lat double
CREATE PROPERTY LivesIn.lng double

CREATE CLASS Follows EXTENDS E

CREATE VERTEX Account SET name='Alice'
CREATE VERTEX Account SET name='Bob', lat=50.503887, lng=4.469936  /* Belgium */
CREATE VERTEX Account SET name='Carol', lat=51.165691, lng=10.451526  /* Germany */
CREATE VERTEX Account SET name='Eve', lat=51.115691, lng=10.481526  /* Germany */
CREATE VERTEX Account SET name='Dave'

CREATE EDGE Follows FROM (SELECT FROM Account WHERE name='Alice') TO (SELECT FROM Account WHERE name='Bob')
CREATE EDGE Follows FROM (SELECT FROM Account WHERE name='Alice') TO (SELECT FROM Account WHERE name='Carol')
CREATE EDGE Follows FROM (SELECT FROM Account WHERE name='Alice') TO (SELECT FROM Account WHERE name='Eve')
CREATE EDGE Follows FROM (SELECT FROM Account WHERE name='Alice') TO (SELECT FROM Account WHERE name='Dave')

CREATE EDGE Follows FROM (SELECT FROM Account WHERE name='Bob') TO (SELECT FROM Account WHERE name='Alice')
CREATE EDGE Follows FROM (SELECT FROM Account WHERE name='Carol') TO (SELECT FROM Account WHERE name='Alice')
CREATE EDGE Follows FROM (SELECT FROM Account WHERE name='Eve') TO (SELECT FROM Account WHERE name='Alice')
CREATE EDGE Follows FROM (SELECT FROM Account WHERE name='Dave') TO (SELECT FROM Account WHERE name='Alice')

CREATE VERTEX Country SET countryname='Belgium'
CREATE VERTEX Country SET countryname='Germany'

CREATE EDGE LivesIn FROM (SELECT FROM Account WHERE name='Bob') TO (SELECT FROM Country WHERE countryname='Belgium') SET lat=50.503887, lng=4.469936
CREATE EDGE LivesIn FROM (SELECT FROM Account WHERE name='Carol') TO (SELECT FROM Country WHERE countryname='Germany') SET lat=51.165691, lng=10.451526
CREATE EDGE LivesIn FROM (SELECT FROM Account WHERE name='Eve') TO (SELECT FROM Country WHERE countryname='Germany') SET lat=51.115691, lng=10.481526

我的问题是,是否有一种有效的方法可以使用 OrientDB 中的特定 sql 命令来实现这一点,或者它是否需要一个新功能。

我想出了一些小事情,比如让所有传出的Follows 连接:

SELECT out("Follows") FROM Account WHERE name='Alice'

但我无法真正从那里获得所有 LivesIn 边缘。

或者,我可以在 OrientDB 中创建一个新函数,就像他们在 here 中所做的那样。比如:

var gdb = orient.getGraphNoTx();
var v = gdb.command("sql", "select from Account where name='" + name + "'");
neighbours = v[0].getRecord().field("out_Follows").iterator();
var result = []
print('\n');
country_dict = {}
while(neighbours.hasNext()) {
    var neighbour = neighbours.next();
    var temp = neighbour.field("in").field("out_LivesIn");
    if(temp) {
        it = temp.iterator();
        print(it.next());
        // Count each country and keep track of sum of lat and lng so it can be divided
        // once all neighbours have been visited
    }
}

但这并没有真正使用任何(可能是有效的?)内置的 sql 方法。考虑到一个人可能会关注数以万计的其他帐户。

有没有人建议我如何解决这个问题?

【问题讨论】:

  • 那么对于 Alice,你会得到 Germany,51.140691,10.466526 Belgium,50.503887,4.469936 对吗?
  • 有点。虽然这些是所有相关国家的平均坐标,但德国在其邻国中出现了两次,而比利时只出现了一次。因此,只有德国的平均坐标基于 Eve 和 Carol 才会返回,因为 Alice 很可能来自那里。

标签: orientdb


【解决方案1】:

试试这个查询

select countryname,eval('sum / _count') as average_lat,eval('sum2 / _count') as average_lng from 
(select countryname,sum(_lat),sum(_lng),count(*) as _count from 
(select outE("livesIn").lat as _lat,outE("livesIn").lng as _lng,out("livesIn").countryname as countryname from 
(select expand(out("Follows")) from Account where name="Alice") unwind _lat,_lng,countryname) 
group by countryname order by _count desc limit 1)

【讨论】:

  • 仅这个查询就可以教会我很多关于语法及其可能性的知识。谢谢!它工作得很好,还可以处理没有连接的用户和连接没有任何位置信息的用户。当您对所有相关国家/地区进行分组并按计数对其进行排序时,我看到它通过选择第一个结果来进行国家/地区选择。这意味着,如果两个国家/地区名列前茅(相同计数),将随机选择一个。那么什么都不返回的好方法是什么?我猜限制为 2 并检查它们是否相同?如果是:停止,否则:继续?
  • 你说得对,我编辑了查询,如果顶部有两个或更多国家/地区,则它们都被选中
  • select countryname,eval('sum / _count') as average_lat,eval('sum2 / _count') as average_lng from (select from (select countryname,sum(_lat),sum(_lng), count() as _count from (select outE("livesIn").lat as _lat,outE("livesIn").lng as _lng,out("livesIn").countryname as countryname from (select expand(out( "Follows")) from Account where name="Alice") unwind _lat,_lng,countryname) group by countryname order by _count desc) where _count in (select max(count) from (select count() from ( select out("Follows").out("livesIn").countryname from Account where name="Alice" unwind out) group by out)))
  • 刚开始测试它,效果很好!它最初给了我一些错误,但是一旦我发现计数缺少一个星号,这很容易解决。非常感谢您花时间帮助我。
猜你喜欢
  • 2010-10-03
  • 1970-01-01
  • 2015-05-17
  • 2011-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-08
相关资源
最近更新 更多