Skip to content

Commit 2633a00

Browse files
author
Mark
committed
Replace graph_edge function with aql
1 parent 4707b56 commit 2633a00

File tree

6 files changed

+220
-66
lines changed

6 files changed

+220
-66
lines changed

src/main/java/com/arangodb/ArangoDriver.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
import com.arangodb.util.AqlQueryOptions;
8080
import com.arangodb.util.DumpHandler;
8181
import com.arangodb.util.GraphEdgesOptions;
82+
import com.arangodb.util.GraphQueryUtil;
8283
import com.arangodb.util.GraphVerticesOptions;
8384
import com.arangodb.util.JsonUtils;
8485
import com.arangodb.util.MapBuilder;
@@ -3516,7 +3517,22 @@ public void deleteGraph(final String graphName, final Boolean dropCollections) t
35163517
* @throws ArangoException
35173518
*/
35183519
public List<String> graphGetVertexCollections(final String graphName) throws ArangoException {
3519-
return graphDriver.getVertexCollections(getDefaultDatabase(), graphName);
3520+
return graphGetVertexCollections(graphName, false);
3521+
}
3522+
3523+
/**
3524+
* Returns a list of all vertex collection of a graph that are defined in
3525+
* the graphs edgeDefinitions (in "from", "to", and "orphanCollections")
3526+
*
3527+
* @param graphName
3528+
* The graph name.
3529+
* @param excludeOrphan
3530+
* @return List<String> List of the names of the vertex collections
3531+
* @throws ArangoException
3532+
*/
3533+
public List<String> graphGetVertexCollections(final String graphName, final boolean excludeOrphan)
3534+
throws ArangoException {
3535+
return graphDriver.getVertexCollections(getDefaultDatabase(), graphName, excludeOrphan);
35203536
}
35213537

35223538
/**
@@ -4368,6 +4384,7 @@ public <T> VertexCursor<T> executeVertexQuery(
43684384
* @return EdgeCursor<T>
43694385
* @throws ArangoException
43704386
*/
4387+
@SuppressWarnings("unchecked")
43714388
public <T> EdgeCursor<T> graphGetEdgeCursor(
43724389
final String graphName,
43734390
final Class<T> clazz,
@@ -4382,17 +4399,20 @@ public <T> EdgeCursor<T> graphGetEdgeCursor(
43824399

43834400
validateCollectionName(graphName);
43844401

4385-
final String query = "for i in graph_edges(@graphName, @vertexExample, @options) return i";
4386-
final Map<String, Object> bindVars = new MapBuilder().put(GRAPH_NAME, graphName)
4387-
.put(VERTEX_EXAMPLE, JsonUtils.convertNullToMap(vertexExample))
4388-
.put("options", JsonUtils.convertNullToMap(tmpGraphEdgesOptions)).get();
4402+
final MapBuilder mapBuilder = new MapBuilder();
4403+
final String query = GraphQueryUtil.createEdgeQuery(this, graphName, clazz, vertexExample, tmpGraphEdgesOptions,
4404+
mapBuilder);
4405+
final Map<String, Object> bindVars = mapBuilder.get();
43894406

43904407
AqlQueryOptions tmpAqlQueryOptions = aqlQueryOptions;
43914408
if (tmpAqlQueryOptions == null) {
43924409
tmpAqlQueryOptions = getDefaultAqlQueryOptions().setCount(true);
43934410
}
43944411

4395-
return executeEdgeQuery(query, bindVars, tmpAqlQueryOptions, clazz);
4412+
DocumentCursorResult<T, EdgeEntity<T>> cursor = executeAqlQueryWithDocumentCursorResult(query, bindVars,
4413+
tmpAqlQueryOptions, EdgeEntity.class, clazz);
4414+
4415+
return new EdgeCursor<T>(cursor);
43964416
}
43974417

43984418
/**

src/main/java/com/arangodb/InternalGraphDriver.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ GraphEntity createGraph(
112112
* @return List<String>
113113
* @throws ArangoException
114114
*/
115-
List<String> getVertexCollections(String databaseName, String graphName) throws ArangoException;
115+
List<String> getVertexCollections(String databaseName, String graphName, boolean excludeOrphan)
116+
throws ArangoException;
116117

117118
/**
118119
*

src/main/java/com/arangodb/impl/InternalGraphDriverImpl.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public class InternalGraphDriverImpl extends BaseArangoDriverWithCursorImpl
5353
private static final String UNKNOWN_ERROR = "unknown error";
5454
private static final String VERTEX = "/vertex";
5555
private static final String EDGE = "/edge";
56+
private static final String EXCLUDE_ORPHAN = "excludeOrphan";
5657

5758
InternalGraphDriverImpl(final ArangoConfigure configure, final InternalCursorDriver cursorDriver,
5859
final HttpManager httpManager) {
@@ -146,10 +147,14 @@ public DeletedEntity deleteGraph(final String databaseName, final String graphNa
146147
}
147148

148149
@Override
149-
public List<String> getVertexCollections(final String databaseName, final String graphName) throws ArangoException {
150+
public List<String> getVertexCollections(
151+
final String databaseName,
152+
final String graphName,
153+
final boolean excludeOrphan) throws ArangoException {
150154
validateCollectionName(graphName);
151-
final HttpResponseEntity res = httpManager
152-
.doGet(createGharialEndpointUrl(databaseName, StringUtils.encodeUrl(graphName), VERTEX));
155+
final HttpResponseEntity res = httpManager.doGet(
156+
createGharialEndpointUrl(databaseName, StringUtils.encodeUrl(graphName), VERTEX),
157+
new MapBuilder().put(EXCLUDE_ORPHAN, excludeOrphan).get());
153158

154159
if (wrongResult(res)) {
155160
throw new ArangoException(UNKNOWN_ERROR);

src/main/java/com/arangodb/util/GraphEdgesOptions.java

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ public class GraphEdgesOptions extends AbstractOptions implements OptionsInterfa
1515
private Object neighborExamples;
1616
private Integer minDepth;
1717
private Integer maxDepth;
18-
private Integer maxIterations;
19-
private Boolean includeData = Boolean.TRUE;
18+
private Integer limit;
19+
private Boolean includeData = Boolean.TRUE;// false = i._id, true = i
2020

2121
/**
2222
* The direction of the edges as a string. Possible values are outbound,
@@ -194,25 +194,12 @@ public GraphEdgesOptions setMaxDepth(Integer maxDepth) {
194194
return this;
195195
}
196196

197-
/**
198-
* the maximum number of iterations that the traversal is allowed to
199-
* perform. It is sensible to set this number so unbounded traversals
200-
*
201-
* @return the maximum number of iterations
202-
*/
203-
public Integer getMaxIterations() {
204-
return maxIterations;
197+
public Integer getLimit() {
198+
return limit;
205199
}
206200

207-
/**
208-
* the maximum number of iterations that the traversal is allowed to
209-
* perform. It is sensible to set this number so unbounded traversals
210-
*
211-
* @return this
212-
* @param maxIterations
213-
*/
214-
public GraphEdgesOptions setMaxIterations(Integer maxIterations) {
215-
this.maxIterations = maxIterations;
201+
public GraphEdgesOptions setLimit(Integer limit) {
202+
this.limit = limit;
216203
return this;
217204
}
218205

@@ -248,7 +235,6 @@ public Map<String, Object> toMap() {
248235
putAttribute(mp, "neighborExamples", neighborExamples);
249236
putAttribute(mp, "minDepth", minDepth);
250237
putAttribute(mp, "maxDepth", maxDepth);
251-
putAttribute(mp, "maxIterations", maxIterations);
252238
putAttribute(mp, "includeData", includeData);
253239

254240
return mp.get();
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package com.arangodb.util;
2+
3+
import java.util.List;
4+
import java.util.Map.Entry;
5+
import java.util.Set;
6+
7+
import com.arangodb.ArangoDriver;
8+
import com.arangodb.ArangoException;
9+
import com.arangodb.Direction;
10+
import com.google.gson.Gson;
11+
import com.google.gson.JsonElement;
12+
import com.google.gson.JsonObject;
13+
14+
/**
15+
* @author Mark - [email protected]
16+
*
17+
*/
18+
public class GraphQueryUtil {
19+
20+
private static final String AND = " && ";
21+
private static final String GRAPH_NAME = "graphName";
22+
private static final String VERTEX_EXAMPLE = "vertexExample";
23+
24+
public static String createEdgeQuery(
25+
final ArangoDriver driver,
26+
final String graphName,
27+
final Class<?> clazz,
28+
final Object vertexExample,
29+
final GraphEdgesOptions graphEdgesOptions,
30+
final MapBuilder bindVars) throws ArangoException {
31+
32+
final StringBuilder sb = new StringBuilder();
33+
if (vertexExample != null && String.class.isAssignableFrom(vertexExample.getClass())) {
34+
sb.append("FOR v,i IN ");
35+
appendDepth(graphEdgesOptions, sb);
36+
appendDirection(graphEdgesOptions, sb);
37+
sb.append(" @");
38+
sb.append(VERTEX_EXAMPLE);
39+
bindVars.put(VERTEX_EXAMPLE, JsonUtils.convertNullToMap(vertexExample));
40+
} else {
41+
final List<String> vertexCollections = driver.graphGetVertexCollections(graphName, true);
42+
if (vertexCollections.size() == 1) {
43+
sb.append("FOR start IN `");
44+
sb.append(vertexCollections.get(0));
45+
sb.append("`");
46+
appendFilter(vertexExample, sb);
47+
} else {
48+
sb.append("FOR start IN UNION (");
49+
for (String vertexCollection : vertexCollections) {
50+
sb.append("(FOR start IN `");
51+
sb.append(vertexCollection);
52+
sb.append("`");
53+
appendFilter(vertexExample, sb);
54+
sb.append(" RETURN start),");
55+
}
56+
// remove last ,
57+
sb.deleteCharAt(sb.length() - 1);
58+
sb.append(")");
59+
}
60+
sb.append(" FOR v,i IN ");
61+
appendDepth(graphEdgesOptions, sb);
62+
appendDirection(graphEdgesOptions, sb);
63+
sb.append(" start");
64+
}
65+
sb.append(" ");
66+
final List<String> edgeCollectionRestriction = graphEdgesOptions.getEdgeCollectionRestriction();
67+
if (edgeCollectionRestriction != null && edgeCollectionRestriction.size() > 0) {
68+
for (String edgeCollection : edgeCollectionRestriction) {
69+
sb.append(edgeCollection);
70+
sb.append(",");
71+
}
72+
// remove last ,
73+
sb.deleteCharAt(sb.length() - 1);
74+
} else {
75+
sb.append("GRAPH @");
76+
sb.append(GRAPH_NAME);
77+
bindVars.put(GRAPH_NAME, graphName);
78+
}
79+
final Integer limit = graphEdgesOptions.getLimit();
80+
if (limit != null) {
81+
sb.append(" LIMIT ");
82+
sb.append(limit.intValue());
83+
}
84+
sb.append(" RETURN distinct i");
85+
if (graphEdgesOptions.getIncludeData() != null && !graphEdgesOptions.getIncludeData().booleanValue()) {
86+
sb.append(".id");
87+
}
88+
89+
final String query = sb.toString();
90+
return query;
91+
}
92+
93+
private static void appendDepth(final GraphEdgesOptions graphEdgesOptions, final StringBuilder sb) {
94+
final Integer minDepth = graphEdgesOptions.getMinDepth();
95+
final Integer maxDepth = graphEdgesOptions.getMaxDepth();
96+
if (minDepth != null || maxDepth != null) {
97+
sb.append(minDepth != null ? minDepth : 1);
98+
sb.append("..");
99+
sb.append(maxDepth != null ? maxDepth : 1);
100+
sb.append(" ");
101+
}
102+
}
103+
104+
private static void appendDirection(final GraphEdgesOptions graphEdgesOptions, final StringBuilder sb) {
105+
final String direction = graphEdgesOptions.getDirection() != null ? graphEdgesOptions.getDirection().name()
106+
: Direction.ANY.name();
107+
sb.append(direction);
108+
}
109+
110+
private static void appendFilter(final Object vertexExample, final StringBuilder sb) {
111+
Gson gson = new Gson();
112+
final JsonElement json = gson.toJsonTree(vertexExample);
113+
if (json.isJsonObject()) {
114+
sb.append(" FILTER ");
115+
final JsonObject jsonObject = json.getAsJsonObject();
116+
final Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
117+
for (Entry<String, JsonElement> entry : entrySet) {
118+
sb.append("start.`");
119+
sb.append(entry.getKey());
120+
sb.append("` == ");
121+
sb.append(entry.getValue().toString());
122+
sb.append(AND);
123+
}
124+
sb.delete(sb.length() - AND.length(), sb.length() - 1);
125+
}
126+
}
127+
128+
public static String createVerticesQuery(
129+
final ArangoDriver driver,
130+
final String graphName,
131+
final Class<?> clazz,
132+
final Object vertexExample,
133+
final GraphVerticesOptions graphVerticesOptions,
134+
final MapBuilder bindVars) throws ArangoException {
135+
return null;
136+
}
137+
138+
public static String createShortestPathQuery(
139+
final ArangoDriver driver,
140+
final String database,
141+
final String graphName,
142+
final Object startVertexExample,
143+
final Object endVertexExample,
144+
final ShortestPathOptions shortestPathOptions,
145+
final Class<?> vertexClass,
146+
final Class<?> edgeClass,
147+
final MapBuilder bindVars) {
148+
return null;
149+
}
150+
}

src/test/java/com/arangodb/ArangoDriverGraphEdgesGetCursorTest.java

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
import com.arangodb.entity.ShortestPathEntity;
3838
import com.arangodb.entity.marker.VertexEntity;
3939
import com.arangodb.util.AqlQueryOptions;
40-
import com.arangodb.util.MapBuilder;
40+
import com.arangodb.util.GraphEdgesOptions;
4141
import com.arangodb.util.ShortestPathOptions;
4242

4343
/**
@@ -228,16 +228,16 @@ public void batchSizeAndLimitTest() throws ArangoException {
228228
final Boolean count = true;
229229
final Boolean fullCount = true;
230230

231-
final String query = "for i in graph_edges(@graphName, null, {includeData: true}) LIMIT 3 return i";
232-
final Map<String, Object> bindVars = new MapBuilder().put("graphName", GRAPH_NAME).get();
231+
GraphEdgesOptions graphEdgesOptions = new GraphEdgesOptions();
232+
graphEdgesOptions.setLimit(3);
233233

234-
final EdgeCursor<TestComplexEntity02> cursor = driver.executeEdgeQuery(query, bindVars,
235-
getAqlQueryOptions(count, batchSize, fullCount), TestComplexEntity02.class);
234+
final EdgeCursor<TestComplexEntity02> cursor = driver.graphGetEdgeCursor(GRAPH_NAME, TestComplexEntity02.class,
235+
null, graphEdgesOptions, getAqlQueryOptions(count, batchSize, fullCount));
236236

237237
assertEquals(3, cursor.getCount());
238238
assertEquals(201, cursor.getCode());
239239
assertTrue(cursor.hasMore());
240-
assertEquals(4, cursor.getFullCount());
240+
assertEquals(8, cursor.getFullCount());
241241
assertTrue(cursor.getCursorId() > -1L);
242242
}
243243

@@ -270,36 +270,28 @@ public void edgesAqlTest() throws ArangoException {
270270
final Boolean count = true;
271271
final Boolean fullCount = true;
272272

273-
// get outbound vertices of vertex1 (the should be 2)
274-
final String query = "for i in graph_edges(@graphName, @vertex, @options) return i";
275-
276-
// options bindVars
277-
final Map<String, Object> options = new MapBuilder().put("direction", "outbound").put("includeData", true)
278-
.get();
279-
280-
// bindVars
281-
Map<String, Object> bindVars = new MapBuilder().put("graphName", GRAPH_NAME)
282-
.put("vertex", vertex1.getDocumentHandle()).put("options", options).get();
283-
284-
EdgeCursor<TestComplexEntity02> cursor = driver.executeEdgeQuery(query, bindVars,
285-
getAqlQueryOptions(count, batchSize, fullCount), TestComplexEntity02.class);
286-
287-
assertEquals(2, cursor.getCount());
288-
assertEquals(201, cursor.getCode());
289-
assertFalse(cursor.hasMore());
290-
assertEquals(new Long(-1L), cursor.getCursorId());
291-
292-
// get outbound vertices of vertex2 (the should be no)
293-
bindVars = new MapBuilder().put("graphName", GRAPH_NAME).put("vertex", vertex2.getDocumentHandle())
294-
.put("options", options).get();
295-
296-
cursor = driver.executeEdgeQuery(query, bindVars, getAqlQueryOptions(count, batchSize, fullCount),
297-
TestComplexEntity02.class);
298-
299-
assertEquals(0, cursor.getCount());
300-
assertEquals(201, cursor.getCode());
301-
assertFalse(cursor.hasMore());
302-
assertEquals(new Long(-1L), cursor.getCursorId());
273+
GraphEdgesOptions graphEdgesOptions = new GraphEdgesOptions();
274+
graphEdgesOptions.setDirection(Direction.OUTBOUND);
275+
graphEdgesOptions.setIncludeData(true);
276+
{
277+
EdgeCursor<TestComplexEntity02> cursor = driver.graphGetEdgeCursor(GRAPH_NAME, TestComplexEntity02.class,
278+
vertex1.getDocumentHandle(), graphEdgesOptions, getAqlQueryOptions(count, batchSize, fullCount));
279+
280+
assertEquals(2, cursor.getCount());
281+
assertEquals(201, cursor.getCode());
282+
assertFalse(cursor.hasMore());
283+
assertEquals(new Long(-1L), cursor.getCursorId());
284+
}
285+
{
286+
// get outbound vertices of vertex2 (the should be no)
287+
EdgeCursor<TestComplexEntity02> cursor = driver.graphGetEdgeCursor(GRAPH_NAME, TestComplexEntity02.class,
288+
vertex2.getDocumentHandle(), graphEdgesOptions, getAqlQueryOptions(count, batchSize, fullCount));
289+
290+
assertEquals(0, cursor.getCount());
291+
assertEquals(201, cursor.getCode());
292+
assertFalse(cursor.hasMore());
293+
assertEquals(new Long(-1L), cursor.getCursorId());
294+
}
303295

304296
}
305297

0 commit comments

Comments
 (0)