簡體   English   中英

Gremlin在Azure CosmosDB上:如何投影相關頂點的屬性?

[英]Gremlin on Azure CosmosDB: how to project the related vertices' properties?

我使用Microsoft.Azure.Graphs庫連接到Cosmos數據庫實例並查詢圖形數據庫。

我正在嘗試優化我的Gremlin查詢,以便僅選擇我只需要的那些屬性。 但是,我不知道如何選擇要從邊和頂點中選擇的屬性。

假設我們從以下查詢開始:

gremlin> g.V().hasLabel('user').
   project('user', 'edges', 'relatedVertices')
     .by()
     .by(bothE().fold())
     .by(both().fold())

這將返回以下內容:

{
    "user": {
        "id": "<userId>",
        "type": "vertex",
        "label": "user",
        "properties": [
            // all vertex properties
        ]
    },
    "edges": [{
        "id": "<edgeId>",
        "type": "edge",
        "label": "<edgeName>",
        "inV": <relatedVertexId>,
        "inVLabel": "<relatedVertexLabel>",
        "outV": "<relatedVertexId>",
        "outVLabel": "<relatedVertexLabel>"
        "properties": [
            // edge properties, if any
        ]
    }],
    "relatedVertices": [{
        "id": "<vertexId>",
        "type": "vertex",
        "label": "<relatedVertexLabel>",
        "properties": [
            // all related vertex properties
        ]
    }]
}

現在假設我們僅從名為“ User”的根頂點獲取幾個屬性:

gremlin> g.V().hasLabel('user').
   project('id', 'prop1', 'prop2', 'edges', 'relatedVertices')
     .by(id)
     .by('prop1')
     .by('prop2')
     .by(bothE().fold())
     .by(both().fold())

這將為我們帶來一些進步,並產生以下收益:

{
    "id": "<userId>",
    "prop1": "value1",
    "prop2": "value2",
    "edges": [{
        "id": "<edgeId>",
        "type": "edge",
        "label": "<edgeName>",
        "inV": <relatedVertexId>,
        "inVLabel": "<relatedVertexLabel>",
        "outV": "<relatedVertexId>",
        "outVLabel": "<relatedVertexLabel>"
        "properties": [
            // edge properties, if any
        ]
    }],
    "relatedVertices": [{
        "id": "<vertexId>",
        "type": "vertex",
        "label": "<relatedVertexLabel>",
        "properties": [
            // all related vertex properties
        ]
    }]
}

現在可以進行類似於邊和相關頂點的操作了嗎? 說,類似以下內容:

gremlin> g.V().hasLabel('user').
   project('id', 'prop1', 'prop2', 'edges', 'relatedVertices')
     .by(id)
     .by('prop1')
     .by('prop2')
     .by(bothE().fold()
         .project('edgeId', 'edgeLabel', 'edgeInV', 'edgeOutV')
              .by(id)
              .by(label)
              .by(inV)
              .by(outV))
     .by(both().fold()
         .project('vertexId', 'someProp1', 'someProp2')
              .by(id)
              .by('someProp1')
              .by('someProp2'))

我的目標是獲得這樣的輸出:

{
    "id": "<userId>",
    "prop1": "value1",
    "prop2": "value2",
    "edges": [{
        "edgeId": "<edgeId>",
        "edgeLabel": "<edgeName>",
        "edgeInV": <relatedVertexId>,
        "edgeOutV": "<relatedVertexId>"
    }],
    "relatedVertices": [{
        "vertexId": "<vertexId>",
        "someProp1": "someValue1",
        "someProp2": "someValue2"
    }]
}

您非常接近:

gremlin> g.V().hasLabel('person').
......1>   project('name','age','edges','relatedVertices').
......2>   by('name').
......3>   by('age').
......4>   by(bothE().
......5>      project('id','inV','outV').
......6>        by(id).
......7>        by(inV().id()).
......8>        by(outV().id()).
......9>      fold()).
.....10>   by(both().
.....11>      project('id','name').
.....12>        by(id).
.....13>        by('name').
.....14>      fold())
==>[name:marko,age:29,edges:[[id:9,inV:3,outV:1],[id:7,inV:2,outV:1],[id:8,inV:4,outV:1]],relatedVertices:[[id:3,name:lop],[id:2,name:vadas],[id:4,name:josh]]]
==>[name:vadas,age:27,edges:[[id:7,inV:2,outV:1]],relatedVertices:[[id:1,name:marko]]]
==>[name:josh,age:32,edges:[[id:10,inV:5,outV:4],[id:11,inV:3,outV:4],[id:8,inV:4,outV:1]],relatedVertices:[[id:5,name:ripple],[id:3,name:lop],[id:1,name:marko]]]
==>[name:peter,age:35,edges:[[id:12,inV:3,outV:6]],relatedVertices:[[id:3,name:lop]]]

編寫Gremlin時應考慮兩點:

  1. 上一步的輸出將輸入到下一步驟的輸入中,如果您不清楚某個特定步驟的結果,那么后面的步驟可能最終不正確。 在您的示例中,在第一個by()您在fold() project()之后添加了project() ,其基本意思是“嘿,Gremlin,為我投影那條邊List ”。 但是在project()by()調制器中,您將要投影的輸入視為List而不是單個邊緣,這很可能導致錯誤。 在Java中,該錯誤是:“ java.util.ArrayList無法轉換為org.apache.tinkerpop.gremlin.structure.Element”。 出現這樣的錯誤是一個提示,表明您在Gremlin的某個地方沒有正確遵循步驟的輸出和輸入。
  2. fold()接受遍歷流中的所有元素,並將其轉換為List 因此,在有許多對象的地方, fold()之后將有一個。 要將它們再次作為流處理,您需要將它們unfold()分開,以便分別對其進行操作。 在這種情況下,我們只需要在對每個邊/頂點執行subproject project()之后將fold()移至語句的末尾。 但是為什么我們根本需要fold() 答案是傳遞給by()調制器的遍歷沒有被其修改的步驟(在本例中為project() )完全迭代。 該步驟僅調用next()來獲取流中的第一個元素-這是設計使然。 因此,在要處理by()的整個流的情況下,必須將流減少為單個對象。 您可以使用fold()來做到這一點,但其他示例包括sum()count()mean()等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM