「JanusGraph-Gremlin」高級語法sack()局部數據結構

sack(麻袋)幫助人們更細緻有效地解決問題

在某些情況下,人們正在編寫使用路徑信息進行數據聚合的Gremlin遍歷。通常,人們將使用path()然後再執行一些過濾以“減少”路徑中的數據獲得特定結果。

不幸的是,這是低效的,因爲路徑計算是昂貴的,且是不可以合併的,計算全部路徑再過濾相當耗資源和時間且笨拙。

 

原理

sack是相對於每個遍歷者的局部數據結構,與aggregate()/store()/group(x)/subgraph(x)...全局數據結構不同。這意味着每個經過路徑的元素都配備了他自己的麻袋。

sack可以包含任何類型的數據結構:

  • 原語:Int,Double,Long,Data...
  • 集合:List,Set,Map

 

Sack的定義

此數據結構的定義應該放在遍歷對象之後:

gremlin>g.withSack(1.0). // Define a sack containing an initial double value        
  V().
  ...
 
gremlin>g.withSack([] as Set). // Define a sack containing an initial empty Set        
  V().
  ...
 
gremlin>g.withSack([1,2,3] as Set). // Define a sack containing a pre-initialized Set        
  V().
  ...
 
gremlin>g.withSack([] as List). // Define a sack containing an initial empty List        
  V().
  ...
 
gremlin>g.withSack([:]). // Define a sack containing an initial empty Map        
  V().
  ...
 
gremlin>g.withSack([:].              // Define a sack containing an initial empty Map  
    withDefault{key -> [] as List}). // with default values being an empty list        
  V().
  ...

withSack()Step的完整參數是 withSack(default_data_structure, split_operator, merge_operator)

  • split_operator:當遍歷器面向分支並需要複製自身時,split運算符用於分割數據結構。示例:V().has("user","userId", "u861").out("rated")。現在,從用戶頂點出現的遍歷與對不同電影的評級一樣多。因此,用戶頂點的sack結構得到重複
  • merge_operator:用於在所有遍歷器收斂到單個點時將不同的數據塊結構合併在一起。示例:g.V().hasLabel("movie").out("director").has("name", "Woody Allen")。來自許多Movie頂點的遍歷正在收斂到單個Person頂點,即Woody Allen。頂點Woody Allen的麻袋是他電影中所有數據結構的合併。如果您沒有定義任何合併運算符,則無法合併

注意:對於原始數據類型,split operator == value copy。對於其他數據類型(如集合),如果未定義任何拆分運算符,則相同的對象引用將複製到所有分支遍歷器。因此,所有這些遍歷者將共享相同的數據結構。要非常小心

 

。。。

 

 

Sack().by()求正弦

gremlin> g.withSack(1).V(1).repeat(sack(sum).by(constant(1))).times(10).emit().sack().math('sin _')
==>0.9092974268256817
==>0.1411200080598672
==>-0.7568024953079282
==>-0.9589242746631385
==>-0.27941549819892586
==>0.6569865987187891
==>0.9893582466233818
==>0.4121184852417566
==>-0.5440211108893698
==>-0.9999902065507035

 

使用sack()進行復雜查詢


/**(43)
 * 使用sack()進行復雜查詢示例
 * */
//(1)
// 普通查詢
//Select all direct flights from SEA to SFO on 8/18/2017, departing time between 6:00 and 10:00 am
g.V().has('StationCode','SEA').
        outE('routes').
            has('LegEffectiveDate',lte(createDate(2017,8,18,0,0,0))).
            has('LegDiscountinueDate',gte(createDate(2017,8,18,0,0,0))).
            has('AircraftSTD',between(createTime(6,0,0),createTime(10,0,0))).
        inV().
            has('StationCode','SFO').path()

//(2)
// 使用sack
//Select all one-stop flights, with one hour connection time, from SFO to SDF on 8/18/2017, departing time between 6:00 and 10:00 am
g.withSack{[M:4472,C:getMaxConnectTime('US','US')]}{it.clone()}.
        V().
            has('StationCode','SFO').
        outE('routes').
            has('LegEffectiveDate',lte(createDate(2017,8,18,0,0,0))).
            has('LegDiscountinueDate',gte(createDate(2017,8,18,0,0,0))).
            has('FlyFri',true).
            has('AircraftSTD',between(createTime(6,0,0),createTime(10,0,0))).
            has('ToAirport',without('SDF')).
            sack{m,e->m['M']=m['M']-e.value('FlightDistance');m['A1']=e.value('AircraftSTA');m}.
            filter{it.sack()['M']>0}.
            order().by('AircraftSTD',incr).
        inV().
        outE('routes').
            has('LegEffectiveDate',lte(createDate(2017,8,18,0,0,0))).
            has('LegDiscountinueDate',gte(createDate(2017,8,18,0,0,0))).
            has('FlyFri',true).
            has('ToAirport','SDF').
            sack{m,e->m['M']=m['M']-e.value('FlightDistance');m['C']=m['C']-getConnectTime(m['A1'],e.value('AircraftSTD'));m}.
            filter{it.sack()['M']>0 && it.sack()['C']>0 && it.get().value('AircraftSTD').after(addTime(it.sack()['A1'],0,60,0))}.
        inV().
        path().
            filter{passCabotage([it.get()[0].value('CountryCode'),it.get()[2].value('CountryCode'),it.get()[4].value('CountryCode')])
                and passNextDay(it.get()[1].value('AircraftSTD'),it.get()[1].value('AircraftSTA'))}

 

未完待續。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章