[ 
https://issues.apache.org/jira/browse/CALCITE-6171?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

ASF GitHub Bot updated CALCITE-6171:
------------------------------------
    Labels: pull-request-available  (was: )

> Support gremlin adapter
> -----------------------
>
>                 Key: CALCITE-6171
>                 URL: https://issues.apache.org/jira/browse/CALCITE-6171
>             Project: Calcite
>          Issue Type: New Feature
>    Affects Versions: 1.36.0
>            Reporter: xingyuan cheng
>            Priority: Major
>              Labels: pull-request-available
>
> h1. Motivation
> Hi, community. Currently, more and more users are using some graph databases, 
> such as JanusGraph, HugeGraph, etc.
> To do some relationship representation of personnel social networks,
> It is used to count the activity of each user in the social network. Most 
> graph databases are in the graph building and graph traversal stage.
> All will be implemented using Gremlin syntax.
> However, this is very unfriendly to users who are not familiar with gremlin 
> syntax. While calcite exists as a query framework,
> It also provides an adapter interface to adapt to different database 
> dialects, such as parsing, relational algebra conversion, and query plan 
> binding.
> Our company has solved the problem of adapting various graph databases. This 
> is my warehouse: [https://github.com/kaori-seasons/calcite-gremlin-sql]
>  
> h2. Background
>  
> Calcite itself supports the database language expansion of the adapter, which 
> enables users to understand the meaning of the grammar.
> Complete the simplification of the dialect. For example, expand SqlNode to 
> implement syntax analysis, and expand RelNode to implement logical plan 
> mapping.
> thinkerpop is an adaptation framework for various graph databases. In this 
> framework, gremlin syntax is mentioned for the first time.
> It has now become a universal query layer for graph databases. While 
> expanding query statements through calcite’s adapter interface,
> We will also use thinkerpop's universal graph database API to provide dialect 
> compatibility for different graph databases.
> Give a simple example:
> From 
> {code:java}
> SELECT "key" FROM inttype{code}
>  maps to
> {code:java}
> g.V().hasLabel("inttype").group().unfold().select(Column.values).order().by(_.unfold().id()).project("inttype").
>  
> by(.project("key").by(.unfold().choose(.has("key"),.values("key"),_.constant("\$%#NULL#
>  %\$")))) {code}
>  
>  
> The design architecture is divided into three layers.
> Analytical syntax layer, relational algebra transformation layer, logical 
> plan binding layer.
> Parsing syntax layer: In the parsing query statement phase, fields and 
> equivalent conditions are split and converted into points and edges.
> Relational algebra layer: Split it into a collection of points and edges, and 
> convert it into a TableScan during the aggregation/sorting/query stage where 
> calcite abstracts it.
> It is convenient to generate query plans based on conditions and field 
> information.
> Connection scanning/single table filtering and other methods can be used to 
> traverse from any edge/any starting point in the graph
> Logical plan binding layer: Bind behaviors such as connection scanning/single 
> table filtering/projection to calcite’s planner to generate query plans.
> The process of generating Gremlin logical plan using select statement:
> 1. First of all, all graph databases start from a source point to build the 
> graph. We will use the GraphTraversalSource provided by thinkerpop.
> As the origin, extract the syntax of the incoming point and side information. 
> This step will be implemented in SqlSchemaGrabber
> 2. Secondly, for select/where/having/order by/group by our plan in the 
> parsing phase is as follows:
> {code:java}
>   - group by: for a point. There are out-degree and in-degree attributes in 
> the graph. From the perspective of the data table, it is equivalent to 
> converting the table data into IN or OUT.
> These two dimensions are aggregated. This behavior also corresponds to the 
> table traversal graph operation. During the graph traversal process, 
> fold/unfold tags will be generated, representing the direction of graph 
> traversal.
>   - select: For the select operation, the operation of scanning the entire 
> table can be regarded as projecting all columns into point attributes. The 
> value changes of each column are mapped to the gremlin operation of adding 
> points.
>   - where: The filter operation is used in graph computing semantic 
> scenarios. It can be regarded as the edges connected by the out-degree and 
> in-degree of the filter point, so it does not involve the conversion of 
> relational algebra.
>   Instead, it is pushed directly to the logical plan.
>   - order by: In the process of graph traversal, we mentioned that 
> fold/unflod will be generated on the path to represent the forward/backward 
> direction.
>   If a field is encountered and there is no value that can be sorted, we will 
> fall back to the origin of GraphTraversalSource and end the sorting operation.
>   If there are values that can be sorted, they will be unified in 
> SqlTraversalEngine, in-degree and out-degree will be counted separately for 
> aggregation, and then used with group by according to label (IN/OUT)
>   - having: The meaning is the same as group by, but the label is different 
> (in addition to the IN/OUT columns, specific point fields need to be 
> specified) {code}
>  
> h2. samples
> Below I will give a simple example using the unit test in my project
> Now suppose there is such a graph data set, there are multiple point sets 🎁 
> and an edge set
> Since the company is connected to the graph database, further testing is 
> needed. I will complete it in the near future //todo
> The point sets respectively represent countries, companies, groups of people, 
> and spatial locations.
>  
> {code:java}
> {
>    "tables": [
>      
> {        "name": "company",        "columns": [          \{"name": "name", 
> "type": "string"}
>        ]
>      },
>      
> {        "name": "country",        "columns": [          \{"name": "name", 
> "type": "string"}
>        ]
>      },
>      
> {        "name": "planet",        "columns": [          \{"name": "name", 
> "type": "string"}
>        ]
>      },
>      
> {        "name": "person",        "columns": [          \{"name": "name", 
> "type": "string"}
> ,
>          {"name": "age", "type": "integer"}
>        ]
>      },
>      
> {        "name": "spaceship",        "columns": [          \{"name": "name", 
> "type": "string"}
> ,
>          {"name": "model", "type": "string"}
>        ]
>      },
>      
> {        "name": "satellite",        "columns": [          \{"name": "name", 
> "type": "string"}
>        ]
>      },
>      
> {        "name": "sensor",        "columns": [          \{"name": "name", 
> "type": "string"}
> ,
>          {"name": "type", "type": "string"}
>        ]
>      },
>      
> {        "name": "sensorReading",        "columns": [          \{"name": 
> "tstamp", "type": "long_timestamp", "propertyName": "timestamp"}
> ,
>          {"name": "dt", "type": "long_date", "propertyName": "date"},
>          {"name": "value", "type": "double"}
>        ]
>      },
>      
> {        "name": "fliesTo",        "columns":[          \{"name": "trips", 
> "type": "integer"}
>        ]
>      },
>      
> {        "name": "orbits",        "columns":[          \{"name": "launched", 
> "type": "integer"}
>        ]
>      }
>      ],
>    "relationships": [
>      {"outTable": "company", "inTable": "country", "edgeLabel": "baseIn"},
>      {"outTable": "person", "inTable": "company", "edgeLabel": "worksFor"},
>      {"outTable": "person", "inTable": "planets", "edgeLabel": "travelledTo"},
>      {"outTable": "company", "inTable": "spaceship", "edgeLabel": "owns"},
>      {"outTable": "person", "inTable": "spaceship", "edgeLabel": "pilots"},
>      {"outTable": "sensor", "inTable": "sensorReading", "edgeLabel": 
> "hasReading", "fkTable": "sensorReading"},
>      {"outTable": "person", "inTable": "planet", "edgeLabel": "fliesTo"},
>      {"outTable": "satellite", "inTable": "planet", "edgeLabel": "orbits"},
>      {"outTable": "person", "inTable": "person", "edgeLabel": "friendsWith"}
>    ]
> } {code}
> Scope of application
> Graph database compatible with thinkerpop's gremlin syntax



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to