Skip to content

Commit ab2b4eb

Browse files
authored
[DE-1070] Configurable label field name (#19)
* configurable label field name * updated documentation * fixed spotbugs checks
1 parent d85ac49 commit ab2b4eb

23 files changed

+160
-86
lines changed

README.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ Graph configuration properties are prefixed with `gremlin.arangodb.conf.graph`:
283283
| `gremlin.arangodb.conf.graph.name` | ArangoDB graph name | `tinkerpop` |
284284
| `gremlin.arangodb.conf.graph.enableDataDefinition` | Flag to allow data definition changes | `false` |
285285
| `gremlin.arangodb.conf.graph.type` | Graph type: `SIMPLE` or `COMPLEX` | `SIMPLE` |
286+
| `gremlin.arangodb.conf.graph.labelField` | Label field name | `_label` |
286287
| `gremlin.arangodb.conf.graph.orphanCollections` | List of orphan collections names | - |
287288
| `gremlin.arangodb.conf.graph.edgeDefinitions` | List of edge definitions | - |
288289

@@ -395,6 +396,11 @@ The ArangoDB TinkerPop Provider supports two graph types, which can be configure
395396
From an application perspective, this is the most flexible graph type that is backed by an ArangoDB graph composed of
396397
only 1 vertex collection and 1 edge definition.
397398

399+
The `label` of each element is stored in a database document field. The label field name is configurable by setting the
400+
configuration property `graph.labelField`, `_label` by default.
401+
402+
The `SIMPLE` graph type is the default graph type.
403+
398404
It has the following advantages:
399405

400406
- It closely matches the Tinkerpop property graph
@@ -407,7 +413,7 @@ It has the following disadvantages:
407413
- All vertex types will be stored in the same vertex collection
408414
- All edge types will be stored in the same edge collection
409415
- It could not leverage the full potential of ArangoDB graph traversal
410-
- It could require an index on the `_label` field to improve performance
416+
- It could require an index on the label field to improve performance
411417

412418
Example configuration:
413419

@@ -443,7 +449,11 @@ to `v/foo`).
443449
### COMPLEX Graph Type
444450

445451
The `COMPLEX` graph type is backed by an ArangoDB graph composed potentially of multiple vertex collections and multiple
446-
edge definitions. It has the following advantages:
452+
edge definitions.
453+
454+
The `label` of each element is used as name for the related database collection.
455+
456+
It has the following advantages:
447457

448458
- It closely matches the ArangoDB graph structure
449459
- It allows multiple vertex collections and multiple edge collections
@@ -502,10 +512,12 @@ collection, by default named `vertex`. In a `COMPLEX` graph, vertices are stored
502512
Each vertex document contains:
503513

504514
- Standard ArangoDB fields (`_id`, `_key`, `_rev`)
505-
- The field `_label`
506515
- Vertex properties as document fields
507516
- Meta-properties nested in the nested map `_meta`
508517

518+
Additionally, in a `SIMPLE` graph:
519+
- The label field (`_label` by default)
520+
509521
For example, the following Java code:
510522

511523
[//]: <> (@formatter:off)
@@ -542,9 +554,11 @@ default named `edge`. In a `COMPLEX` graph, edges are stored in collections name
542554
Each edge document contains:
543555

544556
- Standard ArangoDB edge fields (`_id`, `_key`, `_rev`, `_from`, `_to`)
545-
- The field `_label`
546557
- Edge properties as document fields
547558

559+
Additionally, in a `SIMPLE` graph:
560+
- The label field (`_label` by default)
561+
548562
For example, the following Java code:
549563

550564
[//]: <> (@formatter:off)

spotbugs/spotbugs-exclude.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,9 @@
3030
<Bug pattern="SING_SINGLETON_HAS_NONPRIVATE_CONSTRUCTOR"/>
3131
</Match>
3232

33+
<Match>
34+
<Class name="com.arangodb.tinkerpop.gremlin.persistence.serde.SerdeModule"/>
35+
<Bug pattern="SE_BAD_FIELD"/>
36+
</Match>
37+
3338
</FindBugsFilter>

src/main/java/com/arangodb/tinkerpop/gremlin/client/ArangoDBGraphClient.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public ArangoDBGraphClient(ArangoDBGraphConfig config, ElementIdFactory idFactor
5454
.orElse(ArangoDefaults.DEFAULT_PROTOCOL);
5555
ObjectMapper mapper = JacksonMapperProvider
5656
.of(ContentTypeFactory.of(protocol))
57-
.registerModule(new SerdeModule(idFactory, config.graphType));
57+
.registerModule(new SerdeModule(idFactory, config));
5858
aqlDeserializer = new AqlDeserializer(graph, mapper);
5959
db = new ArangoDB.Builder()
6060
.loadProperties(config.driverConfig)
@@ -305,7 +305,7 @@ public void updateVertex(ArangoDBVertex vertex) {
305305

306306
public Iterator<VertexData> getVertexNeighbors(ElementId vertexId, Set<String> edgeCollections, Direction direction, String[] labels) {
307307
logger.debug("Get vertex {}:{} Neighbors, in {}, from collections {}", vertexId, direction, config.graphName, edgeCollections);
308-
String query = ArangoDBQueryBuilder.readVertexNeighbors(config.graphName, direction, config.graphType, labels);
308+
String query = ArangoDBQueryBuilder.readVertexNeighbors(config.graphName, direction, config, labels);
309309
Map<String, Object> params = new HashMap<>();
310310
params.put("vertexId", vertexId);
311311
params.put("edgeCollections", edgeCollections);
@@ -317,7 +317,7 @@ public Iterator<VertexData> getVertexNeighbors(ElementId vertexId, Set<String> e
317317

318318
public Iterator<EdgeData> getVertexEdges(ElementId vertexId, Set<String> edgeCollections, Direction direction, String[] labels) {
319319
logger.debug("Get vertex {}:{} Edges, in {}, from collections {}", vertexId, direction, config.graphName, edgeCollections);
320-
String query = ArangoDBQueryBuilder.readVertexEdges(config.graphName, direction, config.graphType, labels);
320+
String query = ArangoDBQueryBuilder.readVertexEdges(config.graphName, direction, config, labels);
321321
Map<String, Object> params = new HashMap<>();
322322
params.put("vertexId", vertexId);
323323
params.put("edgeCollections", edgeCollections);

src/main/java/com/arangodb/tinkerpop/gremlin/client/ArangoDBQueryBuilder.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,36 +22,34 @@
2222
import com.arangodb.tinkerpop.gremlin.structure.ArangoDBGraphConfig;
2323
import org.apache.tinkerpop.gremlin.structure.Direction;
2424

25-
import static com.arangodb.tinkerpop.gremlin.utils.Fields.LABEL;
26-
2725

2826
public class ArangoDBQueryBuilder {
2927

3028
private ArangoDBQueryBuilder() {
3129
}
3230

33-
public static String readVertexNeighbors(String graphName, Direction direction, ArangoDBGraphConfig.GraphType type, String[] labels) {
34-
return oneStepTraversal(graphName, direction, type, labels)
31+
public static String readVertexNeighbors(String graphName, Direction direction, ArangoDBGraphConfig config, String[] labels) {
32+
return oneStepTraversal(graphName, direction, config, labels)
3533
.append(" RETURN v")
3634
.toString();
3735
}
3836

39-
public static String readVertexEdges(String graphName, Direction direction, ArangoDBGraphConfig.GraphType type, String[] labels) {
40-
return oneStepTraversal(graphName, direction, type, labels)
37+
public static String readVertexEdges(String graphName, Direction direction, ArangoDBGraphConfig config, String[] labels) {
38+
return oneStepTraversal(graphName, direction, config, labels)
4139
.append(" RETURN e")
4240
.toString();
4341
}
4442

45-
private static StringBuilder oneStepTraversal(String graphName, Direction direction, ArangoDBGraphConfig.GraphType type, String[] labels) {
43+
private static StringBuilder oneStepTraversal(String graphName, Direction direction, ArangoDBGraphConfig config, String[] labels) {
4644
StringBuilder query = new StringBuilder()
4745
.append("FOR v, e IN 1..1 ")
4846
.append(toArangoDirection(direction))
4947
.append(" @vertexId GRAPH ")
5048
.append(escape(graphName))
5149
.append(" OPTIONS {edgeCollections: @edgeCollections}");
5250
if (labels.length > 0) {
53-
if (type == ArangoDBGraphConfig.GraphType.SIMPLE) {
54-
query.append(" FILTER e." + LABEL + " IN @labels");
51+
if (config.graphType == ArangoDBGraphConfig.GraphType.SIMPLE) {
52+
query.append(" FILTER e." + config.labelField + " IN @labels");
5553
} else {
5654
query.append(" FILTER PARSE_COLLECTION(e) IN @edgeCollections");
5755
}

src/main/java/com/arangodb/tinkerpop/gremlin/persistence/serde/EdgeDataDeserializer.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import com.arangodb.tinkerpop.gremlin.persistence.EdgeData;
2020
import com.arangodb.tinkerpop.gremlin.persistence.ElementId;
2121
import com.arangodb.tinkerpop.gremlin.structure.ArangoDBGraphConfig;
22-
import com.arangodb.tinkerpop.gremlin.utils.Fields;
2322
import com.fasterxml.jackson.core.JsonParser;
2423
import com.fasterxml.jackson.core.ObjectCodec;
2524
import com.fasterxml.jackson.databind.DeserializationContext;
@@ -34,10 +33,10 @@
3433

3534
public class EdgeDataDeserializer extends JsonDeserializer<EdgeData> {
3635

37-
private final ArangoDBGraphConfig.GraphType type;
36+
private final ArangoDBGraphConfig config;
3837

39-
public EdgeDataDeserializer(ArangoDBGraphConfig.GraphType type) {
40-
this.type = type;
38+
public EdgeDataDeserializer(ArangoDBGraphConfig config) {
39+
this.config = config;
4140
}
4241

4342
@Override
@@ -46,8 +45,8 @@ public EdgeData deserialize(JsonParser p, DeserializationContext ctx) throws IOE
4645
ObjectNode root = c.readTree(p);
4746
ElementId id = c.treeToValue(root.get(ID), ElementId.class);
4847
String label;
49-
if (type == ArangoDBGraphConfig.GraphType.SIMPLE) {
50-
label = root.get(LABEL).asText();
48+
if (config.graphType == ArangoDBGraphConfig.GraphType.SIMPLE) {
49+
label = root.get(config.labelField).asText();
5150
} else {
5251
label = id.getLabel();
5352
}
@@ -56,7 +55,7 @@ public EdgeData deserialize(JsonParser p, DeserializationContext ctx) throws IOE
5655
EdgeData data = new EdgeData(label, id, from, to);
5756

5857
for (Map.Entry<String, JsonNode> prop : root.properties()) {
59-
if (!Fields.isReserved(prop.getKey())) {
58+
if (!config.isReservedField(prop.getKey())) {
6059
data.put(prop.getKey(), c.treeToValue(prop.getValue(), Object.class));
6160
}
6261
}

src/main/java/com/arangodb/tinkerpop/gremlin/persistence/serde/EdgeDataSerializer.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@
3030

3131
public class EdgeDataSerializer extends JsonSerializer<EdgeData> {
3232

33-
private final ArangoDBGraphConfig.GraphType type;
33+
private final ArangoDBGraphConfig config;
3434

35-
public EdgeDataSerializer(ArangoDBGraphConfig.GraphType type) {
36-
this.type = type;
35+
public EdgeDataSerializer(ArangoDBGraphConfig config) {
36+
this.config = config;
3737
}
3838

3939
@Override
@@ -42,8 +42,8 @@ public void serialize(EdgeData data, JsonGenerator gen, SerializerProvider seria
4242
if (data.getKey() != null) {
4343
gen.writeStringField(Fields.KEY, data.getKey());
4444
}
45-
if (type == ArangoDBGraphConfig.GraphType.SIMPLE) {
46-
gen.writeStringField(LABEL, data.getLabel());
45+
if (config.graphType == ArangoDBGraphConfig.GraphType.SIMPLE) {
46+
gen.writeStringField(config.labelField, data.getLabel());
4747
}
4848
gen.writeObjectField(FROM, data.getFrom());
4949
gen.writeObjectField(TO, data.getTo());

src/main/java/com/arangodb/tinkerpop/gremlin/persistence/serde/SerdeModule.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,27 @@
2424

2525
public class SerdeModule extends SimpleModule {
2626
private final ElementIdFactory idFactory;
27-
private final ArangoDBGraphConfig.GraphType graphType;
27+
private final ArangoDBGraphConfig config;
2828

29-
public SerdeModule(ElementIdFactory idFactory, ArangoDBGraphConfig.GraphType graphType) {
29+
public SerdeModule(ElementIdFactory idFactory, ArangoDBGraphConfig config) {
3030
this.idFactory = idFactory;
31-
this.graphType = graphType;
31+
this.config = config;
3232
}
3333

3434
@Override
3535
public void setupModule(SetupContext context) {
3636
SimpleSerializers serializers = new SimpleSerializers();
3737
serializers.addSerializer(ElementId.class, new ElementIdSerializer());
38-
serializers.addSerializer(VertexData.class, new VertexDataSerializer(graphType));
39-
serializers.addSerializer(EdgeData.class, new EdgeDataSerializer(graphType));
38+
serializers.addSerializer(VertexData.class, new VertexDataSerializer(config));
39+
serializers.addSerializer(EdgeData.class, new EdgeDataSerializer(config));
4040
serializers.addSerializer(VariablesData.class, new VariablesDataSerializer());
4141
context.addSerializers(serializers);
4242

4343
SimpleDeserializers deserializers = new SimpleDeserializers();
4444
deserializers.addDeserializer(ElementId.class, new ElementIdDeserializer(idFactory));
45-
deserializers.addDeserializer(VertexData.class, new VertexDataDeserializer(graphType));
46-
deserializers.addDeserializer(EdgeData.class, new EdgeDataDeserializer(graphType));
47-
deserializers.addDeserializer(VariablesData.class, new VariablesDataDeserializer());
45+
deserializers.addDeserializer(VertexData.class, new VertexDataDeserializer(config));
46+
deserializers.addDeserializer(EdgeData.class, new EdgeDataDeserializer(config));
47+
deserializers.addDeserializer(VariablesData.class, new VariablesDataDeserializer(config));
4848
context.addDeserializers(deserializers);
4949
}
5050
}

src/main/java/com/arangodb/tinkerpop/gremlin/persistence/serde/VariablesDataDeserializer.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
package com.arangodb.tinkerpop.gremlin.persistence.serde;
1818

1919
import com.arangodb.tinkerpop.gremlin.persistence.VariablesData;
20-
import com.arangodb.tinkerpop.gremlin.utils.Fields;
20+
import com.arangodb.tinkerpop.gremlin.structure.ArangoDBGraphConfig;
2121
import com.fasterxml.jackson.core.JsonParser;
2222
import com.fasterxml.jackson.core.ObjectCodec;
2323
import com.fasterxml.jackson.databind.DeserializationContext;
@@ -31,6 +31,12 @@
3131
import static com.arangodb.tinkerpop.gremlin.utils.Fields.*;
3232

3333
public class VariablesDataDeserializer extends JsonDeserializer<VariablesData> {
34+
private final ArangoDBGraphConfig config;
35+
36+
public VariablesDataDeserializer(ArangoDBGraphConfig config) {
37+
this.config = config;
38+
}
39+
3440
@Override
3541
public VariablesData deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
3642
ObjectCodec c = p.getCodec();
@@ -40,7 +46,7 @@ public VariablesData deserialize(JsonParser p, DeserializationContext ctx) throw
4046
VariablesData data = new VariablesData(key, version);
4147

4248
for (Map.Entry<String, JsonNode> prop : root.properties()) {
43-
if (!Fields.isReserved(prop.getKey())) {
49+
if (!config.isReservedField(prop.getKey())) {
4450
data.put(prop.getKey(), c.treeToValue(prop.getValue(), Object.class));
4551
}
4652
}

src/main/java/com/arangodb/tinkerpop/gremlin/persistence/serde/VertexDataDeserializer.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import com.arangodb.tinkerpop.gremlin.persistence.VertexData;
2121
import com.arangodb.tinkerpop.gremlin.persistence.VertexPropertyData;
2222
import com.arangodb.tinkerpop.gremlin.structure.ArangoDBGraphConfig;
23-
import com.arangodb.tinkerpop.gremlin.utils.Fields;
2423
import com.fasterxml.jackson.core.JsonParser;
2524
import com.fasterxml.jackson.core.ObjectCodec;
2625
import com.fasterxml.jackson.databind.DeserializationContext;
@@ -36,10 +35,10 @@
3635

3736
class VertexDataDeserializer extends JsonDeserializer<VertexData> {
3837

39-
private final ArangoDBGraphConfig.GraphType type;
38+
private final ArangoDBGraphConfig config;
4039

41-
VertexDataDeserializer(ArangoDBGraphConfig.GraphType type) {
42-
this.type = type;
40+
VertexDataDeserializer(ArangoDBGraphConfig config) {
41+
this.config = config;
4342
}
4443

4544
@Override
@@ -48,8 +47,8 @@ public VertexData deserialize(JsonParser p, DeserializationContext ctx) throws I
4847
ObjectNode root = c.readTree(p);
4948
ElementId id = c.treeToValue(root.get(ID), ElementId.class);
5049
String label;
51-
if (type == ArangoDBGraphConfig.GraphType.SIMPLE) {
52-
label = root.get(LABEL).asText();
50+
if (config.graphType == ArangoDBGraphConfig.GraphType.SIMPLE) {
51+
label = root.get(config.labelField).asText();
5352
} else {
5453
label = id.getLabel();
5554
}
@@ -60,7 +59,7 @@ public VertexData deserialize(JsonParser p, DeserializationContext ctx) throws I
6059
: Collections.emptyMap();
6160

6261
for (Map.Entry<String, JsonNode> prop : root.properties()) {
63-
if (!Fields.isReserved(prop.getKey())) {
62+
if (!config.isReservedField(prop.getKey())) {
6463
VertexPropertyData pd = new VertexPropertyData(c.treeToValue(prop.getValue(), Object.class));
6564
String key = prop.getKey();
6665
pd.putAll(meta.get(key));

src/main/java/com/arangodb/tinkerpop/gremlin/persistence/serde/VertexDataSerializer.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,12 @@
2828
import java.util.HashMap;
2929
import java.util.Map;
3030

31-
import static com.arangodb.tinkerpop.gremlin.utils.Fields.LABEL;
32-
3331
class VertexDataSerializer extends JsonSerializer<VertexData> {
3432

35-
private final ArangoDBGraphConfig.GraphType type;
33+
private final ArangoDBGraphConfig config;
3634

37-
VertexDataSerializer(ArangoDBGraphConfig.GraphType type) {
38-
this.type = type;
35+
VertexDataSerializer(ArangoDBGraphConfig config) {
36+
this.config = config;
3937
}
4038

4139
@Override
@@ -44,8 +42,8 @@ public void serialize(VertexData data, JsonGenerator gen, SerializerProvider ser
4442
if (data.getKey() != null) {
4543
gen.writeStringField(Fields.KEY, data.getKey());
4644
}
47-
if (type == ArangoDBGraphConfig.GraphType.SIMPLE) {
48-
gen.writeStringField(LABEL, data.getLabel());
45+
if (config.graphType == ArangoDBGraphConfig.GraphType.SIMPLE) {
46+
gen.writeStringField(config.labelField, data.getLabel());
4947
}
5048

5149
Map<String, Map<String, Object>> meta = new HashMap<>();

0 commit comments

Comments
 (0)