2012-10-30 8 views
5

Ich entwickle eine Anwendung, die mit einer Graph-Datenbank gut funktionieren könnte (Titan), außer es Probleme mit den Eckpunkten mit vielen Kanten, das heißt supernodes.„Superknoten“ in Titan

Der oben genannte Link verweist auf einen Blogeintrag der Autoren von Titan und erklärt, wie das Problem gelöst werden kann. Die Lösung scheint die Anzahl der Scheitelpunkte zu reduzieren, indem an Kanten gefiltert wird.

Leider möchte ich groupCount Attribute von Kanten oder Scheitelpunkte. Zum Beispiel habe ich 1 Million Benutzer und jeder Benutzer gehört zu einem Land. Wie kann ich eine schnelle groupCount machen, um die Anzahl der Benutzer in jedem Land zu ermitteln?

Was ich bisher versucht, kann in diesem aufwändigen groovy Skript angezeigt:

g = TitanFactory.open('titan.properties') // Cassandra 
r = new Random(100) 
people = 1e6 

def newKey(g, name, type) { 
    return g 
     .makeType() 
     .name(name) 
     .simple() 
     .functional() 
     .indexed() 
     .dataType(type) 
     .makePropertyKey() 
} 

def newLabel(g, name, key) { 
    return g 
     .makeType() 
     .name(name) 
     .primaryKey(key) 
     .makeEdgeLabel() 
} 

country = newKey(g, 'country', String.class) 
newLabel(g, 'lives', country) 

g.stopTransaction(SUCCESS) 

root = g.addVertex() 
countries = ['AU', 'US', 'CN', 'NZ', 'UK', 'PL', 'RU', 'NL', 'FR', 'SP', 'IT'] 

(1..people).each { 
    country = countries[(r.nextFloat() * countries.size()).toInteger()] 
    g.startTransaction() 
    person = g.addVertex([name: 'John the #' + it]) 
    g.addEdge(g.getVertex(root.id), person, 'lives', [country: country]) 
    g.stopTransaction(SUCCESS) 
} 

t0 = new Date().time 

m = [:]  
root = g.getVertex(root.id) 
root.outE('lives').country.groupCount(m).iterate() 

t1 = new Date().time 

println "groupCount seconds: " + ((t1 - t0)/1000) 

Grundsätzlich ein Wurzelknoten (aus Gründen der Titan nicht einen „all“ Knoten-Lookup mit), verbunden mit vielen person über Kanten, die die country Eigenschaft haben. Wenn ich den groupCount() auf 1 Million Vertices ausführe, dauert es mehr als eine Minute.

Ich realisiere, dass Titan wahrscheinlich über jede Kante iteriert und Zählungen sammelt, aber gibt es eine Möglichkeit, dies in Titan oder einer anderen Graphdatenbank schneller zu machen? Kann der Index selbst gezählt werden, damit er nicht durchlaufen werden muss? Sind meine Indizes korrekt?

Antwort

8

Wenn Sie "Land" ein primary key für das Label "Leben" machen, können Sie alle Personen für ein bestimmtes Land schneller abrufen. In Ihrem Fall sind Sie jedoch an einer Gruppenzählung interessiert, bei der alle Kanten dieses Stammknotens abgerufen werden müssen, um über sie zu iterieren und die Länder zu erfassen.

Daher ist diese analytische Abfrage viel besser geeignet für das Graph Analytics Framework Faunus. Es benötigt keinen Wurzelknoten, da es die Gruppenzählung über einen vollständigen Datenbank-Scan ausführt und somit das Supernode-Problem vermeidet. Faunus verwendet auch Gremlin als Abfragesprache, so dass Sie nur Ihre Abfrage etwas ändern müssen:

g.V.country.groupCount.cap... 

HTH, Matthias