blob: b990a54a2e980f8d5cd5c52a76993c6f7fb19602 [file] [log] [blame] [view]
---
title: "Edge API"
linkTitle: "Edge"
weight: 8
---
### 2.2 Edge
The modification of the vertex ID format also affects the ID of the edge, as well as the formats of the source vertex and target vertex IDs.
The EdgeId is formed by concatenating `src-vertex-id + direction + label + sort-values + tgt-vertex-id`, but the vertex ID types are not distinguished by quotation marks here. Instead, they are distinguished by prefixes:
- When the ID type is number, the vertex ID in the EdgeId has a prefix `L`, like "L123456>1>>L987654".
- When the ID type is string, the vertex ID in the EdgeId has a prefix `S`, like "S1:peter>1>>S2:lop".
--------------------------------------------------------------------------------
The following example requires creating a graph `schema` based on the following `groovy` script:
```groovy
import org.apache.hugegraph.HugeFactory
import org.apache.tinkerpop.gremlin.structure.T
conf = "conf/graphs/hugegraph.properties"
graph = HugeFactory.open(conf)
schema = graph.schema()
schema.propertyKey("name").asText().ifNotExist().create()
schema.propertyKey("age").asInt().ifNotExist().create()
schema.propertyKey("city").asText().ifNotExist().create()
schema.propertyKey("weight").asDouble().ifNotExist().create()
schema.propertyKey("lang").asText().ifNotExist().create()
schema.propertyKey("date").asText().ifNotExist().create()
schema.propertyKey("price").asInt().ifNotExist().create()
schema.vertexLabel("person").properties("name", "age", "city").primaryKeys("name").ifNotExist().create()
schema.vertexLabel("software").properties("name", "lang", "price").primaryKeys("name").ifNotExist().create()
schema.indexLabel("personByCity").onV("person").by("city").secondary().ifNotExist().create()
schema.indexLabel("personByAgeAndCity").onV("person").by("age", "city").secondary().ifNotExist().create()
schema.indexLabel("softwareByPrice").onV("software").by("price").range().ifNotExist().create()
schema.edgeLabel("knows").sourceLabel("person").targetLabel("person").properties("date", "weight").ifNotExist().create()
schema.edgeLabel("created").sourceLabel("person").targetLabel("software").properties("date", "weight").ifNotExist().create()
schema.indexLabel("createdByDate").onE("created").by("date").secondary().ifNotExist().create()
schema.indexLabel("createdByWeight").onE("created").by("weight").range().ifNotExist().create()
schema.indexLabel("knowsByWeight").onE("knows").by("weight").range().ifNotExist().create()
marko = graph.addVertex(T.label, "person", "name", "marko", "age", 29, "city", "Beijing")
vadas = graph.addVertex(T.label, "person", "name", "vadas", "age", 27, "city", "Hongkong")
lop = graph.addVertex(T.label, "software", "name", "lop", "lang", "java", "price", 328)
josh = graph.addVertex(T.label, "person", "name", "josh", "age", 32, "city", "Beijing")
ripple = graph.addVertex(T.label, "software", "name", "ripple", "lang", "java", "price", 199)
peter = graph.addVertex(T.label, "person", "name", "peter", "age", 35, "city", "Shanghai")
graph.tx().commit()
g = graph.traversal()
```
#### 2.2.1 Creating an Edge
##### Params
**Path Parameter Description:**
- graph: The graph to operate on
**Request Body Description:**
- label: The edge type name (required)
- outV: The source vertex id (required)
- inV: The target vertex id (required)
- outVLabel: The source vertex type (required)
- inVLabel: The target vertex type (required)
- properties: The properties associated with the edge. The internal structure of the object is as follows:
1. name: The property name
2. value: The property value
##### Method & Url
```
POST http://localhost:8080/graphs/hugegraph/graph/edges
```
##### Request Body
```json
{
"label": "created",
"outV": "1:marko",
"inV": "2:lop",
"outVLabel": "person",
"inVLabel": "software",
"properties": {
"date": "20171210",
"weight": 0.4
}
}
```
##### Response Status
```json
201
```
##### Response Body
```json
{
"id": "S1:marko>2>>S2:lop",
"label": "created",
"type": "edge",
"outV": "1:marko",
"outVLabel": "person",
"inV": "2:lop",
"inVLabel": "software",
"properties": {
"weight": 0.4,
"date": "20171210"
}
}
```
#### 2.2.2 Creating Multiple Edges
##### Params
**Path Parameter Description:**
- graph: The graph to operate on
**Request Parameter Description:**
- check_vertex: Whether to check the existence of vertices (true | false). When set to true, an error will be thrown if the source or target vertices of the edge to be inserted do not exist. Default is true.
**Request Body Description:**
- List of edge information
##### Method & Url
```
POST http://localhost:8080/graphs/hugegraph/graph/edges/batch
```
##### Request Body
```json
[
{
"label": "knows",
"outV": "1:marko",
"inV": "1:vadas",
"outVLabel": "person",
"inVLabel": "person",
"properties": {
"date": "20160110",
"weight": 0.5
}
},
{
"label": "knows",
"outV": "1:marko",
"inV": "1:josh",
"outVLabel": "person",
"inVLabel": "person",
"properties": {
"date": "20130220",
"weight": 1.0
}
}
]
```
##### Response Status
```json
201
```
##### Response Body
```json
[
"S1:marko>1>>S1:vadas",
"S1:marko>1>>S1:josh"
]
```
#### 2.2.3 Updating Edge Properties
##### Params
**Path Parameter Description:**
- graph: The graph to operate on
- id: The ID of the edge to be operated on
**Request Parameter Description:**
- action: The append action
**Request Body Description:**
- Edge information
##### Method & Url
```
PUT http://localhost:8080/graphs/hugegraph/graph/edges/S1:marko>2>>S2:lop?action=append
```
##### Request Body
```json
{
"properties": {
"weight": 1.0
}
}
```
> NOTE: There are three categories of property values: single, set, and list. If it is single, it means adding or updating the property value. If it is set or list, it means appending the property value.
##### Response Status
```json
200
```
##### Response Body
```json
{
"id": "S1:marko>2>>S2:lop",
"label": "created",
"type": "edge",
"outV": "1:marko",
"outVLabel": "person",
"inV": "2:lop",
"inVLabel": "software",
"properties": {
"weight": 1.0,
"date": "20171210"
}
}
```
#### 2.2.4 Batch Updating Edge Properties
##### Params
**Path Parameter Description:**
- graph: The graph to operate on
**Request Body Description:**
- edges: List of edge information
- update_strategies: For each property, you can set its update strategy individually, including:
- SUM: Only supports number type
- BIGGER/SMALLER: Only supports date/number type
- UNION/INTERSECTION: Only supports set type
- APPEND/ELIMINATE: Only supports collection type
- OVERRIDE
- check_vertex: Whether to check the existence of vertices (true | false). When set to true, an error will be thrown if the source or target vertices of the edge to be inserted do not exist. Default is true.
- create_if_not_exist: Currently only supports setting to true
##### Method & Url
```
PUT http://127.0.0.1:8080/graphs/hugegraph/graph/edges/batch
```
##### Request Body
```json
{
"edges": [
{
"label": "knows",
"outV": "1:marko",
"inV": "1:vadas",
"outVLabel": "person",
"inVLabel": "person",
"properties": {
"date": "20160111",
"weight": 1.0
}
},
{
"label": "knows",
"outV": "1:marko",
"inV": "1:josh",
"outVLabel": "person",
"inVLabel": "person",
"properties": {
"date": "20130221",
"weight": 0.5
}
}
],
"update_strategies": {
"weight": "SUM",
"date": "OVERRIDE"
},
"check_vertex": false,
"create_if_not_exist": true
}
```
##### Response Status
```json
200
```
##### Response Body
```json
{
"edges": [
{
"id": "S1:marko>1>>S1:vadas",
"label": "knows",
"type": "edge",
"outV": "1:marko",
"outVLabel": "person",
"inV": "1:vadas",
"inVLabel": "person",
"properties": {
"weight": 1.5,
"date": "20160111"
}
},
{
"id": "S1:marko>1>>S1:josh",
"label": "knows",
"type": "edge",
"outV": "1:marko",
"outVLabel": "person",
"inV": "1:josh",
"inVLabel": "person",
"properties": {
"weight": 1.5,
"date": "20130221"
}
}
]
}
```
#### 2.2.5 Deleting Edge Properties
##### Params
**Path Parameter Description:**
- graph: The graph to operate on
- id: The ID of the edge to be operated on
**Request Parameter Description:**
- action: The eliminate action
**Request Body Description:**
- Edge information
##### Method & Url
```
PUT http://localhost:8080/graphs/hugegraph/graph/edges/S1:marko>2>>S2:lop?action=eliminate
```
##### Request Body
```json
{
"properties": {
"weight": 1.0
}
}
```
> NOTE: This will directly delete the properties (removing the key and all values), regardless of whether the property values are single, set, or list.
##### Response Status
```json
400
```
##### Response Body
It is not possible to delete an attribute that is not set as nullable.
```json
{
"exception": "class java.lang.IllegalArgumentException",
"message": "Can't remove non-null edge property 'p[weight->1.0]'",
"cause": ""
}
```
#### 2.2.6 Fetching Edges that Match the Criteria
##### Params
**Path Parameter:**
- graph: The graph to operate on
**Request Parameters:**
- vertex_id: Vertex ID
- direction: Edge direction (OUT | IN | BOTH), default is BOTH
- label: Edge label
- properties: Key-value pairs of properties (requires pre-built indexes for property queries)
- keep_start_p: Default is false. When set to true, the range matching input expression will not be automatically escaped. For example, `properties={"age":"P.gt(0.8)"}` will be interpreted as an exact match, i.e., the age property is equal to "P.gt(0.8)"
- offset: Offset, default is 0
- limit: Number of queries, default is 100
- page: Page number
Key-value pairs of properties consist of the property name and value in JSON format. Multiple key-value pairs are allowed as query conditions. Property values support exact matching and range matching. For exact matching, it is in the form `properties={"weight":0.8}`. For range matching, it is in the form `properties={"age":"P.gt(0.8)"}`. The expressions supported by range matching are as follows:
| Expression | Description |
|------------------------------------|----------------------------------------------------------------------------------|
| P.eq(number) | Edges with property value equal to number |
| P.neq(number) | Edges with property value not equal to number |
| P.lt(number) | Edges with property value less than number |
| P.lte(number) | Edges with property value less than or equal to number |
| P.gt(number) | Edges with property value greater than number |
| P.gte(number) | Edges with property value greater than or equal to number |
| P.between(number1,number2) | Edges with property value greater than or equal to number1 and less than number2 |
| P.inside(number1,number2) | Edges with property value greater than number1 and less than number2 |
| P.outside(number1,number2) | Edges with property value less than number1 and greater than number2 |
| P.within(value1,value2,value3,...) | Edges with property value equal to any of the given values |
| P.textcontains(value) | Edges with property value containing the given value (string type) |
| P.contains(value) | Edges with property value containing the given value (collection type) |
**Edges connected to the vertex person:marko(vertex_id="1:marko") with label knows and date property equal to "20160111"**
##### Method & Url
```
GET http://127.0.0.1:8080/graphs/hugegraph/graph/edges?vertex_id="1:marko"&label=knows&properties={"date":"P.within(\"20160111\")"}
```
##### Response Status
```json
200
```
##### Response Body
```json
{
"edges": [
{
"id": "S1:marko>1>>S1:vadas",
"label": "knows",
"type": "edge",
"outV": "1:marko",
"outVLabel": "person",
"inV": "1:vadas",
"inVLabel": "person",
"properties": {
"weight": 1.5,
"date": "20160111"
}
}
]
}
```
**Paginate and retrieve all edges, get the first page (page without parameter value), limit to 2 entries**
##### Method & Url
```
GET http://127.0.0.1:8080/graphs/hugegraph/graph/edges?page&limit=2
```
##### Response Status
```json
200
```
##### Response Body
```json
{
"edges": [
{
"id": "S1:marko>1>>S1:josh",
"label": "knows",
"type": "edge",
"outV": "1:marko",
"outVLabel": "person",
"inV": "1:josh",
"inVLabel": "person",
"properties": {
"weight": 1.5,
"date": "20130221"
}
},
{
"id": "S1:marko>1>>S1:vadas",
"label": "knows",
"type": "edge",
"outV": "1:marko",
"outVLabel": "person",
"inV": "1:vadas",
"inVLabel": "person",
"properties": {
"weight": 1.5,
"date": "20160111"
}
}
],
"page": "EoYxOm1hcmtvgggCAIQyOmxvcAAAAAAAAAAC"
}
```
The returned body contains the page number information for the next page, `"page": "EoYxOm1hcmtvgggCAIQyOmxvcAAAAAAAAAAC"`. When querying the next page, assign this value to the page parameter.
**Paginate and retrieve all edges, get the next page (include the page value returned from the previous page), limit to 2 entries**
##### Method & Url
```
GET http://127.0.0.1:8080/graphs/hugegraph/graph/edges?page=EoYxOm1hcmtvgggCAIQyOmxvcAAAAAAAAAAC&limit=2
```
##### Response Status
```json
200
```
##### Response Body
```json
{
"edges": [
{
"id": "S1:marko>2>>S2:lop",
"label": "created",
"type": "edge",
"outV": "1:marko",
"outVLabel": "person",
"inV": "2:lop",
"inVLabel": "software",
"properties": {
"weight": 1.0,
"date": "20171210"
}
}
],
"page": null
}
```
When `"page": null` is returned, it indicates that there are no more pages available.
> NOTE: When the backend is Cassandra, for performance considerations, if the returned page happens to be the last page, the `page` value may not be empty. When requesting the next page data using that `page` value, it will return `empty data` and `page = null`. Similar situations apply for other cases.
#### 2.2.7 Fetching Edge by ID
##### Params
**Path parameter description:**
- graph: The graph to be operated on.
- id: The ID of the edge to be operated on.
##### Method & Url
```
GET http://localhost:8080/graphs/hugegraph/graph/edges/S1:marko>2>>S2:lop
```
##### Response Status
```json
200
```
##### Response Body
```json
{
"id": "S1:marko>2>>S2:lop",
"label": "created",
"type": "edge",
"outV": "1:marko",
"outVLabel": "person",
"inV": "2:lop",
"inVLabel": "software",
"properties": {
"weight": 1.0,
"date": "20171210"
}
}
```
#### 2.2.8 Deleting Edge by ID
##### Params
**Path parameter description:**
- graph: The graph to be operated on.
- id: The ID of the edge to be operated on.
**Request parameter description:**
- label: The label of the edge.
**Deleting Edge by ID only**
##### Method & Url
```
DELETE http://localhost:8080/graphs/hugegraph/graph/edges/S1:marko>2>>S2:lop
```
##### Response Status
```json
204
```
**Deleting Edge by Label + ID**
In general, specifying the Label parameter along with the ID to delete an edge will provide better performance compared to deleting by ID only.
##### Method & Url
```
DELETE http://localhost:8080/graphs/hugegraph/graph/edges/S1:marko>1>>S1:vadas?label=knows
```
##### Response Status
```json
204
```