diff --git a/gradoop-examples/src/main/java/org/gradoop/examples/io/EdgeListExample.java b/gradoop-examples/src/main/java/org/gradoop/examples/io/EdgeListExample.java index 5140666bd22f..51ad3712e2ee 100644 --- a/gradoop-examples/src/main/java/org/gradoop/examples/io/EdgeListExample.java +++ b/gradoop-examples/src/main/java/org/gradoop/examples/io/EdgeListExample.java @@ -21,6 +21,10 @@ import org.gradoop.flink.io.impl.edgelist.EdgeListDataSource; import org.gradoop.flink.model.api.epgm.GraphCollection; import org.gradoop.flink.model.api.epgm.LogicalGraph; +import org.gradoop.flink.model.impl.operators.matching.common.MatchStrategy; +import org.gradoop.flink.model.impl.operators.matching.common.query.DFSTraverser; +import org.gradoop.flink.model.impl.operators.matching.single.preserving.explorative.ExplorativePatternMatching; +import org.gradoop.flink.model.impl.operators.matching.single.preserving.explorative.traverser.TraverserStrategy; import org.gradoop.flink.util.GradoopFlinkConfig; /** @@ -83,8 +87,14 @@ public static void main(String[] args) throws Exception { }); // do some analytics (e.g. match two-node cycles) - GraphCollection matches = logicalGraph - .match("(a:Node)-[:link]->(b:Node)-[:link]->(a)"); + String query = "(a:Node)-[:link]->(b:Node)-[:link]->(a)"; + ExplorativePatternMatching patternMatchingOperator = new ExplorativePatternMatching.Builder() + .setQuery(query) + .setAttachData(true) + .setMatchStrategy(MatchStrategy.ISOMORPHISM) + .setTraverserStrategy(TraverserStrategy.SET_PAIR_BULK_ITERATION) + .setTraverser(new DFSTraverser()).build(); + GraphCollection matches = logicalGraph.callForCollection(patternMatchingOperator); // print number of matching subgraphs System.out.println(matches.getGraphHeads().count()); diff --git a/gradoop-examples/src/main/java/org/gradoop/examples/patternmatching/CypherExample.java b/gradoop-examples/src/main/java/org/gradoop/examples/patternmatching/CypherExample.java index ff55a2939474..c6dbb9dd60d3 100644 --- a/gradoop-examples/src/main/java/org/gradoop/examples/patternmatching/CypherExample.java +++ b/gradoop-examples/src/main/java/org/gradoop/examples/patternmatching/CypherExample.java @@ -61,7 +61,7 @@ public static void main(String[] args) throws Exception { // run a Cypher query (vertex homomorphism, edge isomorphism) // the result is a graph collection containing all matching subgraphs - GraphCollection matches = socialNetwork.cypher( + GraphCollection matches = socialNetwork.query( "MATCH (u1:Person)<-[:hasModerator]-(f:Forum)" + "(u2:Person)<-[:hasMember]-(f)" + "WHERE u1.name = \"Alice\"", statistics); diff --git a/gradoop-flink/src/main/java/org/gradoop/flink/model/api/epgm/LogicalGraph.java b/gradoop-flink/src/main/java/org/gradoop/flink/model/api/epgm/LogicalGraph.java index 6b193512824a..c14a24d04664 100644 --- a/gradoop-flink/src/main/java/org/gradoop/flink/model/api/epgm/LogicalGraph.java +++ b/gradoop-flink/src/main/java/org/gradoop/flink/model/api/epgm/LogicalGraph.java @@ -47,11 +47,8 @@ import org.gradoop.flink.model.impl.operators.grouping.GroupingStrategy; import org.gradoop.flink.model.impl.operators.grouping.functions.aggregation.PropertyValueAggregator; import org.gradoop.flink.model.impl.operators.matching.common.MatchStrategy; -import org.gradoop.flink.model.impl.operators.matching.common.query.DFSTraverser; import org.gradoop.flink.model.impl.operators.matching.common.statistics.GraphStatistics; import org.gradoop.flink.model.impl.operators.matching.single.cypher.CypherPatternMatching; -import org.gradoop.flink.model.impl.operators.matching.single.preserving.explorative.ExplorativePatternMatching; -import org.gradoop.flink.model.impl.operators.matching.single.preserving.explorative.traverser.TraverserStrategy; import org.gradoop.flink.model.impl.operators.neighborhood.Neighborhood; import org.gradoop.flink.model.impl.operators.neighborhood.ReduceEdgeNeighborhood; import org.gradoop.flink.model.impl.operators.neighborhood.ReduceVertexNeighborhood; @@ -174,6 +171,7 @@ public DataSet getIncomingEdges(GradoopId vertexID) { * {@inheritDoc} */ @Override + @Deprecated public GraphCollection cypher(String query) { return cypher(query, new GraphStatistics(1, 1, 1, 1)); } @@ -182,6 +180,7 @@ public GraphCollection cypher(String query) { * {@inheritDoc} */ @Override + @Deprecated public GraphCollection cypher(String query, String constructionPattern) { return cypher(query, constructionPattern, new GraphStatistics(1, 1, 1, 1)); } @@ -190,6 +189,7 @@ public GraphCollection cypher(String query, String constructionPattern) { * {@inheritDoc} */ @Override + @Deprecated public GraphCollection cypher(String query, GraphStatistics graphStatistics) { return cypher(query, true, MatchStrategy.HOMOMORPHISM, MatchStrategy.ISOMORPHISM, graphStatistics); @@ -199,6 +199,7 @@ public GraphCollection cypher(String query, GraphStatistics graphStatistics) { * {@inheritDoc} */ @Override + @Deprecated public GraphCollection cypher(String query, String constructionPattern, GraphStatistics graphStatistics) { return cypher(query, constructionPattern, true, @@ -210,6 +211,7 @@ public GraphCollection cypher(String query, String constructionPattern, * {@inheritDoc} */ @Override + @Deprecated public GraphCollection cypher(String query, boolean attachData, MatchStrategy vertexStrategy, MatchStrategy edgeStrategy, GraphStatistics graphStatistics) { return cypher(query, null, attachData, vertexStrategy, edgeStrategy, graphStatistics); @@ -219,6 +221,7 @@ public GraphCollection cypher(String query, boolean attachData, MatchStrategy ve * {@inheritDoc} */ @Override + @Deprecated public GraphCollection cypher(String query, String constructionPattern, boolean attachData, MatchStrategy vertexStrategy, MatchStrategy edgeStrategy, GraphStatistics graphStatistics) { return callForCollection(new CypherPatternMatching(query, constructionPattern, attachData, @@ -229,34 +232,56 @@ public GraphCollection cypher(String query, String constructionPattern, boolean * {@inheritDoc} */ @Override - public GraphCollection match(String pattern) { - return match(pattern, true); + public GraphCollection query(String query) { + return query(query, new GraphStatistics(1, 1, 1, 1)); } /** * {@inheritDoc} */ @Override - public GraphCollection match(String pattern, boolean attachData) { - return match(pattern, attachData, MatchStrategy.ISOMORPHISM, - TraverserStrategy.SET_PAIR_BULK_ITERATION); + public GraphCollection query(String query, String constructionPattern) { + return query(query, constructionPattern, new GraphStatistics(1, 1, 1, 1)); } /** * {@inheritDoc} */ @Override - public GraphCollection match(String pattern, boolean attachData, - MatchStrategy matchStrategy, TraverserStrategy traverserStrategy) { + public GraphCollection query(String query, GraphStatistics graphStatistics) { + return query(query, true, + MatchStrategy.HOMOMORPHISM, MatchStrategy.ISOMORPHISM, graphStatistics); + } + + /** + * {@inheritDoc} + */ + @Override + public GraphCollection query(String query, String constructionPattern, + GraphStatistics graphStatistics) { + return query(query, constructionPattern, true, + MatchStrategy.HOMOMORPHISM, MatchStrategy.ISOMORPHISM, graphStatistics); + } + - ExplorativePatternMatching op = new ExplorativePatternMatching.Builder() - .setQuery(pattern) - .setAttachData(attachData) - .setMatchStrategy(matchStrategy) - .setTraverserStrategy(traverserStrategy) - .setTraverser(new DFSTraverser()).build(); + /** + * {@inheritDoc} + */ + @Override + public GraphCollection query(String query, boolean attachData, MatchStrategy vertexStrategy, + MatchStrategy edgeStrategy, GraphStatistics graphStatistics) { + return query(query, null, attachData, vertexStrategy, edgeStrategy, graphStatistics); + } - return callForCollection(op); + /** + * {@inheritDoc} + */ + @Override + public GraphCollection query(String query, String constructionPattern, boolean attachData, + MatchStrategy vertexStrategy, MatchStrategy edgeStrategy, + GraphStatistics graphStatistics) { + return callForCollection(new CypherPatternMatching(query, constructionPattern, attachData, + vertexStrategy, edgeStrategy, graphStatistics)); } /** diff --git a/gradoop-flink/src/main/java/org/gradoop/flink/model/api/epgm/LogicalGraphOperators.java b/gradoop-flink/src/main/java/org/gradoop/flink/model/api/epgm/LogicalGraphOperators.java index b300cf976d83..4d4e14223bec 100644 --- a/gradoop-flink/src/main/java/org/gradoop/flink/model/api/epgm/LogicalGraphOperators.java +++ b/gradoop-flink/src/main/java/org/gradoop/flink/model/api/epgm/LogicalGraphOperators.java @@ -34,7 +34,6 @@ import org.gradoop.flink.model.impl.operators.grouping.functions.aggregation.PropertyValueAggregator; import org.gradoop.flink.model.impl.operators.matching.common.MatchStrategy; import org.gradoop.flink.model.impl.operators.matching.common.statistics.GraphStatistics; -import org.gradoop.flink.model.impl.operators.matching.single.preserving.explorative.traverser.TraverserStrategy; import org.gradoop.flink.model.impl.operators.neighborhood.Neighborhood; import org.gradoop.flink.model.impl.operators.subgraph.Subgraph; @@ -61,7 +60,10 @@ public interface LogicalGraphOperators extends GraphBaseOperators { * * @param query Cypher query * @return graph collection containing matching subgraphs + * @deprecated because of API restructuring. + * Please use {@link LogicalGraph#query(String)} instead. */ + @Deprecated GraphCollection cypher(String query); /** @@ -90,7 +92,10 @@ public interface LogicalGraphOperators extends GraphBaseOperators { * @param query Cypher query string * @param constructionPattern Construction pattern * @return graph collection containing the output of the construct pattern + * @deprecated because of API restructuring. + * Please use {@link LogicalGraph#query(String, String)} instead. */ + @Deprecated GraphCollection cypher(String query, String constructionPattern); /** @@ -101,7 +106,10 @@ public interface LogicalGraphOperators extends GraphBaseOperators { * @param query Cypher query * @param graphStatistics statistics about the data graph * @return graph collection containing matching subgraphs + * @deprecated because of API restructuring. + * Please use {@link LogicalGraph#query(String, GraphStatistics)} instead. */ + @Deprecated GraphCollection cypher(String query, GraphStatistics graphStatistics); /** @@ -127,7 +135,10 @@ public interface LogicalGraphOperators extends GraphBaseOperators { * @param constructionPattern Construction pattern * @param graphStatistics statistics about the data graph * @return graph collection containing the output of the construct pattern + * @deprecated because of API restructuring. + * Please use {@link LogicalGraph#query(String, String, GraphStatistics)} instead. */ + @Deprecated GraphCollection cypher(String query, String constructionPattern, GraphStatistics graphStatistics); /** @@ -139,7 +150,10 @@ public interface LogicalGraphOperators extends GraphBaseOperators { * @param edgeStrategy morphism setting for edge mapping * @param graphStatistics statistics about the data graph * @return graph collection containing matching subgraphs + * @deprecated because of API restructuring. + * Please use {@link LogicalGraph#query(String, boolean, MatchStrategy, MatchStrategy, GraphStatistics)} instead. */ + @Deprecated GraphCollection cypher(String query, boolean attachData, MatchStrategy vertexStrategy, MatchStrategy edgeStrategy, GraphStatistics graphStatistics); @@ -153,47 +167,119 @@ GraphCollection cypher(String query, boolean attachData, * @param edgeStrategy morphism setting for edge mapping * @param graphStatistics statistics about the data graph * @return graph collection containing matching subgraphs + * @deprecated because of API restructuring. + * Please use {@link LogicalGraph#query(String, String, boolean, MatchStrategy, MatchStrategy, GraphStatistics)} instead. */ + @Deprecated GraphCollection cypher(String query, String constructionPattern, boolean attachData, MatchStrategy vertexStrategy, MatchStrategy edgeStrategy, GraphStatistics graphStatistics); /** - * Evaluates the given GDL query using the Traverser query engine. + * Evaluates the given query using the Cypher query engine. The engine uses default morphism + * strategies, which is vertex homomorphism and edge isomorphism. The vertex and edge data of + * the data graph elements is attached to the resulting vertices. * - * @param pattern GDL graph pattern + * Note, that this method used no statistics about the data graph which may result in bad + * runtime performance. Use {@link LogicalGraphOperators#query(String, GraphStatistics)} to + * provide statistics for the query planner. * - * @return subgraphs of the input graph that match the given graph pattern + * @param query Cypher query + * @return graph collection containing matching subgraphs */ - GraphCollection match(String pattern); + GraphCollection query(String query); /** - * Evaluates the given GDL query using the Traverser query engine. + * Evaluates the given query using the Cypher query engine. The engine uses default morphism + * strategies, which is vertex homomorphism and edge isomorphism. The vertex and edge data of + * the data graph elements is attached to the resulting vertices. * - * This method allows to control if the original vertex and edge data - * (labels and properties) shall be attached to the resulting subgraphs. - * Note that this requires additional JOIN operations. + * Note, that this method used no statistics about the data graph which may result in bad + * runtime performance. Use {@link LogicalGraphOperators#query(String, GraphStatistics)} to + * provide statistics for the query planner. * - * @param pattern GDL graph pattern - * @param attachData attach original vertex and edge data to the result - * @return subgraphs of the input graph that match the given graph pattern + * In addition, the operator can be supplied with a construction pattern allowing the creation + * of new graph elements based on variable bindings of the match pattern. Consider the following + * example: + * + *
+   * graph.query(
+   *  "MATCH (a:Author)-[:WROTE]->(:Paper)<-[:WROTE]-(b:Author) WHERE a <> b",
+   *  "(a)-[:CO_AUTHOR]->(b)")
+   * 
+   * 
+ * + * The query pattern is looking for pairs of authors that worked on the same paper. The + * construction pattern defines a new edge of type CO_AUTHOR between the two entities. + * + * @param query Cypher query string + * @param constructionPattern Construction pattern + * @return graph collection containing the output of the construct pattern */ - GraphCollection match(String pattern, boolean attachData); + GraphCollection query(String query, String constructionPattern); /** - * Evaluates the given GDL query using the Traverser query engine. + * Evaluates the given query using the Cypher query engine. The engine uses default morphism + * strategies, which is vertex homomorphism and edge isomorphism. The vertex and edge data of + * the data graph elements is attached to the resulting vertices. * - * This method allows to control the match strategy. This influences mostly - * if vertices and edges can be matched to multiple vertices/edges in the - * query. + * @param query Cypher query + * @param graphStatistics statistics about the data graph + * @return graph collection containing matching subgraphs + */ + GraphCollection query(String query, GraphStatistics graphStatistics); + + /** + * Evaluates the given query using the Cypher query engine. The engine uses default morphism + * strategies, which is vertex homomorphism and edge isomorphism. The vertex and edge data of + * the data graph elements is attached to the resulting vertices. * - * @param pattern GDL graph pattern - * @param attachData attach original vertex and edge data to the result - * @param matchStrategy strategy for vertex and edge mappings - * @param iterationStrategy strategy for internal iteration - * @return subgraphs of the input graph that match the given graph pattern + * In addition, the operator can be supplied with a construction pattern allowing the creation + * of new graph elements based on variable bindings of the match pattern. Consider the following + * example: + * + *
+   * graph.query(
+   *  "MATCH (a:Author)-[:WROTE]->(:Paper)<-[:WROTE]-(b:Author) WHERE a <> b",
+   *  "(a)-[:CO_AUTHOR]->(b)")
+   * 
+   * 
+ * + * The query pattern is looking for pairs of authors that worked on the same paper. The + * construction pattern defines a new edge of type CO_AUTHOR between the two entities. + * + * @param query Cypher query + * @param constructionPattern Construction pattern + * @param graphStatistics statistics about the data graph + * @return graph collection containing the output of the construct pattern + */ + GraphCollection query(String query, String constructionPattern, GraphStatistics graphStatistics); + + /** + * Evaluates the given query using the Cypher query engine. + * + * @param query Cypher query + * @param attachData attach original vertex and edge data to the result + * @param vertexStrategy morphism setting for vertex mapping + * @param edgeStrategy morphism setting for edge mapping + * @param graphStatistics statistics about the data graph + * @return graph collection containing matching subgraphs + */ + GraphCollection query(String query, boolean attachData, MatchStrategy vertexStrategy, + MatchStrategy edgeStrategy, GraphStatistics graphStatistics); + + /** + * Evaluates the given query using the Cypher query engine. + * + * @param query Cypher query + * @param constructionPattern Construction pattern + * @param attachData attach original vertex and edge data to the result + * @param vertexStrategy morphism setting for vertex mapping + * @param edgeStrategy morphism setting for edge mapping + * @param graphStatistics statistics about the data graph + * @return graph collection containing matching subgraphs */ - GraphCollection match(String pattern, boolean attachData, - MatchStrategy matchStrategy, TraverserStrategy iterationStrategy); + GraphCollection query(String query, String constructionPattern, boolean attachData, + MatchStrategy vertexStrategy, MatchStrategy edgeStrategy, GraphStatistics graphStatistics); /** * Creates a copy of the logical graph. diff --git a/gradoop-flink/src/test/java/org/gradoop/flink/model/impl/operators/matching/single/cypher/CypherGraphConstructionTest.java b/gradoop-flink/src/test/java/org/gradoop/flink/model/impl/operators/matching/single/cypher/CypherGraphConstructionTest.java index 43769c68d894..4bc3b66b48b6 100644 --- a/gradoop-flink/src/test/java/org/gradoop/flink/model/impl/operators/matching/single/cypher/CypherGraphConstructionTest.java +++ b/gradoop-flink/src/test/java/org/gradoop/flink/model/impl/operators/matching/single/cypher/CypherGraphConstructionTest.java @@ -38,7 +38,7 @@ public void testEdgeConstruction() throws Exception { "(bob)-[:possible_friend]->(dave)" + "]"); - GraphCollection result = dbGraph.cypher( + GraphCollection result = dbGraph.query( "MATCH (a:Person)-[e0:knows]->(b:Person)-[e1:knows]->(c:Person) " + "WHERE a.city = 'Leipzig' AND a <> c", "(b)<-[e0]-(a)-[e_new:possible_friend]->(c)<-[e1]-(b)"); @@ -62,7 +62,7 @@ public void testEdgeConstructionReducedPattern() throws Exception { "(bob)-[:possible_friend]->(dave)" + "]"); - GraphCollection result = dbGraph.cypher( + GraphCollection result = dbGraph.query( "MATCH (a:Person)-[:knows]->(b:Person)-[:knows]->(c:Person) " + "WHERE a.city = 'Leipzig' AND a <> c", "(a)-[e_new:possible_friend]->(c)"); @@ -86,7 +86,7 @@ public void testEdgeConstructionExtendedPattern() throws Exception { "(bob)-[:possible_friend]->(:possible_person)-[:possible_friend]->(dave)" + "]"); - GraphCollection result = dbGraph.cypher( + GraphCollection result = dbGraph.query( "MATCH (a:Person)-[:knows]->(b:Person)-[:knows]->(c:Person) " + "WHERE a.city = 'Leipzig' AND a <> c", "(a)-[e_new:possible_friend]->(v_new:possible_person)-[e_new2:possible_friend]->(c)");