社交類業務場景的數據模型天然具備高度連接的特點,圖數據庫GDB可以為社交類業務提供天然的圖模型支持,更加完美的匹配和理解您的數據。使用圖數據庫GDB,可以顯著提升社交類業務程序的開發效率和質量,減少數據模型轉換帶來的額外損耗。

1、數據模型

以社交領域公開數據集Twitter社交關系為例。更多信息,請參見數據模型參考下載

圖數據庫GDB使用屬性圖模型來表示和處理數據,可以將數據模型抽象為下圖:
說明
  • User:用戶節點。
  • Follow:代表單向的好友關系。比如關注,或者是對方的粉絲。
示例數據如下:
  • 點文件:
    ~id,name:string
    1,a0e05a4a-65c0-11e9-a5ce-00163e0416f8
    2,a0e05e28-65c0-11e9-a5ce-00163e0416f8
    3,a0e05f86-65c0-11e9-a5ce-00163e0416f8
    4,a0e0606c-65c0-11e9-a5ce-00163e0416f8
    5,a0e0613e-65c0-11e9-a5ce-00163e0416f8
    6,a0e06206-65c0-11e9-a5ce-00163e0416f8
  • 邊文件:
    ~id,~from,~to,weight:double
    212416660,1116299,4377946,0.443259
    212416661,1116300,4377946,0.0303036
    212416662,181406,4377946,0.753659
    212416663,4084735,4377946,0.991974
    212416664,1937755,4377946,0.79248

2、創建實例

創建圖數據庫實例。具體操作,請參見創建主實例
說明
  • 實例購買成功后,您可以在實例列表頁面查看實例相關信息。通常,實例創建成功需要3~5分鐘。
  • 創建GDB實例后,您需要創建賬號和密碼、設置安全組,保證您具有GDB實例的訪問權限。具體操作,請參見創建賬號設置白名單

3、數據導入

圖數據庫GDB支持從多種數據源將數據導入至圖數據庫GDB,您可以使用以下兩種方式進行數據導入:

4、連接實例

圖數據庫GDB支持多種方法連接實例,您可以通過以下五種方式連接實例:
  • 通過GDB控制臺直接登錄數據管理服務DMS,更加方便快捷地遠程訪問、在線管理您的GDB數據庫。具體操作,請參見通過DMS登錄GDB數據庫
  • 通過開源組件GDB Console可視化控制臺登錄圖數據庫,可視化界面,操作簡單,并可根據業務需求對可視化界面進行二次開發。具體操作,請參見通過開源組件GDB Console登錄圖數據庫
  • 通過Gremlin Console連接實例,命令行模式,適合Gremlin內核版本,適合用于查詢語句性能優化。具體操作,請參見通過Gremlin Console連接實例
  • 通過Cypher Shell連接實例,命令行模式,適合Cypher內核版本。具體操作,請參見通過Cypher Shell連接實例
  • 通過SDK連接,支持Java、Python、.Net、Go、Node.js五種SDK。具體操作,請參見SDK參考

5、使用范例

  • 簡單查詢
    • 數據統計:
      //統計點的數目
      gremlin> g.V().count()
      ==>41999999
      
      //統計邊的數目
      gremlin> g.E().count()
      ==>22191165
    • 過濾查詢、排序查詢:
      //查詢name為a0e05a4a-65c0-11e9-a5ce-00163e0416f8的用戶。
      gremlin> g.V().has('name','a0e05a4a-65c0-11e9-a5ce-00163e0416f8').valueMap(true)   //條件查詢,類似select ... where ...,根據業務修改has()中的內容即可。
      ==>[id:1,label:vertex,name:[a0e05a4a-65c0-11e9-a5ce-00163e0416f8]]
      
      //查詢name為a0e05a4a-65c0-11e9-a5ce-00163e0416f8的用戶的關注列表。
      gremlin> g.V().has('name','a0e05a4a-65c0-11e9-a5ce-00163e0416f8').outE().valueMap(true) //條件查詢,類似select ... where ...,根據業務修改has()中的內容即可
      ==>[id:217089344,label:edge,weight:0.769055]
      ==>[id:220429042,label:edge,weight:0.290449]
      ==>[id:227652991,label:edge,weight:0.962171]
      ==>[id:234881614,label:edge,weight:0.0887247]
      ==>[id:250193757,label:edge,weight:0.756271]
      ==>[id:252223359,label:edge,weight:0.990445]
      ==>[id:252494754,label:edge,weight:0.494867]
      ==>[id:254012304,label:edge,weight:0.788503]
      ==>[id:260893506,label:edge,weight:0.247677]
      ==>[id:228404583,label:edge,weight:0.0742597]
      ==>[id:243912806,label:edge,weight:0.906016]
      ==>[id:262031400,label:edge,weight:0.649892]
      
      //查詢name為a0e05a4a-65c0-11e9-a5ce-00163e0416f8的用戶的關注列表,并按照權重倒序排序。
      gremlin> g.V().has('name','a0e05a4a-65c0-11e9-a5ce-00163e0416f8').outE().order().by('weight', decr).valueMap(true) //has()部分控制查詢條件,order().by()部分控制排序條件。
      ==>[id:252223359,label:edge,weight:0.990445]
      ==>[id:227652991,label:edge,weight:0.962171]
      ==>[id:243912806,label:edge,weight:0.906016]
      ==>[id:254012304,label:edge,weight:0.788503]
      ==>[id:217089344,label:edge,weight:0.769055]
      ==>[id:250193757,label:edge,weight:0.756271]
      ==>[id:262031400,label:edge,weight:0.649892]
      ==>[id:310064671,label:edge,weight:0.639453]
      ==>[id:316084412,label:edge,weight:0.595669]
      ==>[id:277559997,label:edge,weight:0.538571]
      ==>[id:252494754,label:edge,weight:0.494867]
      ==>[id:291708246,label:edge,weight:0.387777]
      ==>[id:281304400,label:edge,weight:0.382627]
      ==>[id:310008546,label:edge,weight:0.333313]
      ==>[id:220429042,label:edge,weight:0.290449]
      ==>[id:260893506,label:edge,weight:0.247677]
      ==>[id:300018487,label:edge,weight:0.228707]
      ==>[id:234881614,label:edge,weight:0.0887247]
      ==>[id:289510146,label:edge,weight:0.078113]
      ==>[id:228404583,label:edge,weight:0.0742597]
      5.1
  • 通用場景:
    • k階鄰居:
      //查詢用戶ID為23的2跳關注關系。
      gremlin> g.V(23).repeat(outE('edge').otherV().simplePath()).times(2).path() //outE()部分控制查詢邊類型,times()部分查詢深度。
      ==>[v[23],e[239197952][23-edge->19201],v[19201],e[229218134][19201-edge->18246],v[18246]]
      ==>[v[23],e[239197952][23-edge->19201],v[19201],e[216091024][19201-edge->2586961],v[2586961]]
      ==>[v[23],e[267069904][23-edge->2587481],v[2587481],e[225145280][2587481-edge->1018015],v[1018015]]
      ==>[v[23],e[267069904][23-edge->2587481],v[2587481],e[284567757][2587481-edge->1022162],v[1022162]]
      ==>[v[23],e[267069904][23-edge->2587481],v[2587481],e[235313604][2587481-edge->10467758],v[10467758]]
      ==>[v[23],e[267069904][23-edge->2587481],v[2587481],e[265280161][2587481-edge->15350178],v[15350178]]
      ==>[v[23],e[267069904][23-edge->2587481],v[2587481],e[280654355][2587481-edge->1796334],v[1796334]]
      ......
      5.3
    • 最短路徑:
      //查詢ID為23和ID為5924864 的最短路徑,最大深度為2。
      gremlin> g.V(23).repeat(bothE().otherV().simplePath())
                  .until(hasId(5924864).or().loops().is(gt(2L)))  //hasId()部分控制結束ID,gt()部分查詢深度。
                      .hasId(5924864).path().dedup()
      ==>[v[23],v[2587481],v[5924864]]
      5.4
    • 共同鄰居:
      //查詢ID為23和ID為5924864的共同鄰居。
      gremlin> g.V(23).repeat(bothE().otherV().simplePath()).times(2).hasId(5924864).path().dedup()  //hasId()部分控制結束ID。
      ==>[v[23],e[267069904][23-edge->2587481],v[2587481],e[267070009][5924864-edge->2587481],v[5924864]]
      5.5
    • 大V查找:
      //社交場景中,大V往往是根據粉絲的數量來衡量,粉絲越多說明越受歡迎,我們要找到擁有粉絲最多的三個大V。
      gremlin> g.V().project('user','degree').by().by(inE().count()).order().by(select('degree'), desc).limit(3) // by(inE().count()) 部分控制統計邏輯,order().by(select('degree'), desc).limit(3) 控制排序邏輯
      ==>[v[23],e[267069904][23-edge->2587481],v[2587481],e[267070009][5924864-edge->2587481],v[5924864]]
      ==>[v[23],e[267069904][23-edge->2587481],v[2587481],e[316011732][2587481-edge->5924864],v[5924864]]
      ==>[user:v[1],degree:1090]
      ==>[user:v[24],degree:890]
      ==>[user:v[65],degree:768]
    • 協同推薦:
      //推薦和ID為1的用戶,有共同鄰居的用戶,并按照共同鄰居的個數進行排序。
      gremlin> g.V(1).both().aggregate("my_friend").both().has(id, neq(1)).as("ff")
                  .flatMap(__.both().where(within("my_friend")).count()).as("comm_cnt").order().by(desc)
                      .select("ff", "comm_cnt").dedup()
      ==>[ff:v[591712],comm_cnt:10]
      ==>[ff:v[60911],comm_cnt:10]
      ==>[ff:v[4470],comm_cnt:10]
      ==>[ff:v[47129],comm_cnt:10]
      ==>[ff:v[1],comm_cnt:10]
      ==>[ff:v[316284],comm_cnt:10]
      ==>[ff:v[472652],comm_cnt:9]
      ==>[ff:v[52057],comm_cnt:9]
      ==>[ff:v[531386],comm_cnt:9]
      ...

6、 客戶效果

某社交領域互聯網公司,圖數據規模為點(用戶數據)1億,邊(社交關系)16億,之前通過MySQL存儲(32core,256GB),面臨MySQL查詢性能過低的問題,經常出現查詢超時。通過使用圖數據庫GDB,以用戶為節點、用戶在線狀態為屬性,好友關系為邊構建社交圖譜,查詢性能提升超過100倍,從超時提升到毫秒級。