def test_variable_length_path(self): node0 = Node(node_id=0, label="L1") node1 = Node(node_id=1, label="L1") node2 = Node(node_id=2, label="L1") edge01 = Edge(node0, "R1", node1, edge_id=0, properties={'value': 1}) edge12 = Edge(node1, "R1", node2, edge_id=1, properties={'value': 2}) redis_graph.add_node(node0) redis_graph.add_node(node1) redis_graph.add_node(node2) redis_graph.add_edge(edge01) redis_graph.add_edge(edge12) redis_graph.flush() path01 = Path.new_empty_path().add_node(node0).add_edge( edge01).add_node(node1) path12 = Path.new_empty_path().add_node(node1).add_edge( edge12).add_node(node2) path02 = Path.new_empty_path().add_node(node0).add_edge( edge01).add_node(node1).add_edge(edge12).add_node(node2) expected_results = [[path01], [path12], [path02]] query = "MATCH p=(:L1)-[:R1*]->(:L1) RETURN p" query_info = QueryInfo(query=query, description="Tests variable length paths", expected_result=expected_results) self._assert_resultset_and_expected_mutually_included( redis_graph.query(query), query_info)
def test07_test_edge_filters(self): node0 = Node(node_id=0, label="L", properties={'x': 'a'}) node1 = Node(node_id=1, label="L", properties={'x': 'b'}) node2 = Node(node_id=2, label="L", properties={'x': 'c'}) edge01 = Edge(src_node=node0, dest_node=node1, relation="R", properties={'x': 1}) edge12 = Edge(src_node=node1, dest_node=node2, relation="R") redis_graph.add_node(node0) redis_graph.add_node(node1) redis_graph.add_node(node2) redis_graph.add_edge(edge01) redis_graph.add_edge(edge12) redis_graph.flush() query = "MATCH (n:L) WHERE (n)-[:R {x:1}]->() RETURN n.x" result_set = redis_graph.query(query) expected_results = [['a']] query_info = QueryInfo( query=query, description="Tests pattern filter edge conditions", expected_result=expected_results) self._assert_resultset_and_expected_mutually_included( result_set, query_info)
def worstcase(r: Redis): g = Graph('simple_2', r) v0 = Node(properties={'name': 'v0'}) v1 = Node(properties={'name': 'v1'}) v2 = Node(properties={'name': 'v2'}) v3 = Node(properties={'name': 'v3'}) v4 = Node(properties={'name': 'v4'}) g.add_node(v0) g.add_node(v1) g.add_node(v2) g.add_node(v3) g.add_node(v4) e1 = Edge(v0, 'A', v1, properties={'name': 'r1'}) e2 = Edge(v1, 'A', v2, properties={'name': 'r2'}) e3 = Edge(v2, 'A', v0, properties={'name': 'r3'}) e4 = Edge(v0, 'B', v3, properties={'name': 'r5'}) e5 = Edge(v3, 'B', v0, properties={'name': 'r6'}) g.add_edge(e1) g.add_edge(e2) g.add_edge(e3) g.add_edge(e4) g.add_edge(e5) g.commit() return g
def test15_assign_entity_properties(self): # merge attribute set of a node with existing properties node = Node(label="L", properties={"v1": 1, "v2": 2}) result = multiple_entity_graph.query( "MATCH (n1 {v1: 1}), (n2 {v2: 2}) SET n1 += n2 RETURN n1") expected_result = [[node]] self.env.assertEqual(result.result_set, expected_result) # validate index updates result = multiple_entity_graph.query( "MATCH (n:L) WHERE n.v1 > 0 RETURN n.v1 ORDER BY n.v1") expected_result = [[1]] self.env.assertEqual(result.result_set, expected_result) result = multiple_entity_graph.query( "MATCH (n:L) WHERE n.v2 > 0 RETURN n.v2 ORDER BY n.v2") expected_result = [[2], [2]] self.env.assertEqual(result.result_set, expected_result) # overwrite attribute set of node with attribute set of edge node = Node(label="L", properties={"v1": 3}) result = multiple_entity_graph.query( "MATCH (n {v1: 1})-[e]->() SET n = e RETURN n") expected_result = [[node]] self.env.assertEqual(result.result_set, expected_result) # validate index updates result = multiple_entity_graph.query( "MATCH (n:L) WHERE n.v1 > 0 RETURN n.v1 ORDER BY n.v1") expected_result = [[3]] self.env.assertEqual(result.result_set, expected_result) result = multiple_entity_graph.query( "MATCH (n:L) WHERE n.v2 > 0 RETURN n.v2 ORDER BY n.v2") expected_result = [[2]] self.env.assertEqual(result.result_set, expected_result)
def test_simple_path(self): node0 = Node(node_id=0, label="L1") node1 = Node(node_id=1, label="L1") node2 = Node(node_id=2, label="L1") edge01 = Edge(node0, "R1", node1, edge_id=0, properties={'value': 1}) edge12 = Edge(node1, "R1", node2, edge_id=1, properties={'value': 2}) redis_graph.add_node(node0) redis_graph.add_node(node1) redis_graph.add_node(node2) redis_graph.add_edge(edge01) redis_graph.add_edge(edge12) redis_graph.flush() # Rewrite the edges with IDs instead of node values to match how they are returned. edge01 = Edge(0, "R1", 1, edge_id=0, properties={'value': 1}) edge12 = Edge(1, "R1", 2, edge_id=1, properties={'value': 2}) path01 = Path.new_empty_path().add_node(node0).add_edge( edge01).add_node(node1) path12 = Path.new_empty_path().add_node(node1).add_edge( edge12).add_node(node2) expected_results = [[path01], [path12]] query = "MATCH p=(:L1)-[:R1]->(:L1) RETURN p" query_info = QueryInfo(query=query, description="Tests simple paths", expected_result=expected_results) self._assert_resultset_and_expected_mutually_included( redis_graph.query(query), query_info)
def test15_update_deleted_entities(self): self.env.flush() redis_con = self.env.getConnection() redis_graph = Graph("delete_test", redis_con) src = Node() dest = Node() edge = Edge(src, "R", dest) redis_graph.add_node(src) redis_graph.add_node(dest) redis_graph.add_edge(edge) redis_graph.flush() # Attempt to update entities after deleting them. query = """MATCH (a)-[e]->(b) DELETE a, b SET a.v = 1, e.v = 2, b.v = 3""" actual_result = redis_graph.query(query) self.env.assertEquals(actual_result.nodes_deleted, 2) self.env.assertEquals(actual_result.relationships_deleted, 1) # No properties should be set. # (Note that this behavior is left unspecified by Cypher.) self.env.assertEquals(actual_result.properties_set, 0) # Validate that the graph is empty. query = """MATCH (a) RETURN a""" actual_result = redis_graph.query(query) expected_result = [] self.env.assertEquals(actual_result.result_set, expected_result)
def test_bi_directional_path(self): node0 = Node(node_id=0, label="L1") node1 = Node(node_id=1, label="L1") node2 = Node(node_id=2, label="L1") edge01 = Edge(node0, "R1", node1, edge_id=0, properties={'value': 1}) edge12 = Edge(node1, "R1", node2, edge_id=1, properties={'value': 2}) redis_graph.add_node(node0) redis_graph.add_node(node1) redis_graph.add_node(node2) redis_graph.add_edge(edge01) redis_graph.add_edge(edge12) redis_graph.flush() # Reverse direction edges which are not part of the graph. Read only values. edge10 = Edge(1, "R1", 0, edge_id = 0 , properties={'value':1}) edge21 = Edge(2, "R1", 1, edge_id = 1 , properties={'value':2}) path010 = Path.new_empty_path().add_node(node0).add_edge(edge01).add_node(node1).add_edge(edge10).add_node(node0) path0121 = Path.new_empty_path().add_node(node0).add_edge(edge01).add_node(node1).add_edge(edge12) \ .add_node(node2).add_edge(edge21).add_node(node1) path01210 = Path.new_empty_path().add_node(node0).add_edge(edge01).add_node(node1).add_edge(edge12) \ .add_node(node2).add_edge(edge21).add_node(node1).add_edge(edge10).add_node(node0) path121 = Path.new_empty_path().add_node(node1).add_edge(edge12).add_node(node2).add_edge(edge21).add_node(node1) path1210 = Path.new_empty_path().add_node(node1).add_edge(edge12).add_node(node2).add_edge(edge21) \ .add_node(node1).add_edge(edge10).add_node(node0) expected_results=[[path010], [path0121], [path01210], [path121], [path1210]] query = "MATCH p=(:L1)-[:R1*]->(:L1)<-[:R1*]-() RETURN p" query_info = QueryInfo(query = query, description="Tests bi directional variable length paths", \ expected_result = expected_results) self._assert_resultset_and_expected_mutually_included(redis_graph.query(query), query_info)
def test11_bidirectional_multiple_edge_type(self): # Construct a simple graph: # (a)-[E1]->(b), (c)-[E2]->(d) g = Graph("multi_edge_type", redis_con) a = Node(properties={'val': 'a'}) b = Node(properties={'val': 'b'}) c = Node(properties={'val': 'c'}) d = Node(properties={'val': 'd'}) g.add_node(a) g.add_node(b) g.add_node(c) g.add_node(d) ab = Edge(a, "E1", b) cd = Edge(c, "E2", d) g.add_edge(ab) g.add_edge(cd) g.flush() query = """MATCH (a)-[:E1|:E2]-(z) RETURN a.val, z.val ORDER BY a.val, z.val""" actual_result = g.query(query) expected_result = [['a', 'b'], ['b', 'a'], ['c', 'd'], ['d', 'c']] self.env.assertEquals(actual_result.result_set, expected_result)
def test_multi_hashjoins(self): # See issue https://github.com/RedisGraph/RedisGraph/issues/1124 # Construct a 4 node graph, (v1),(v2),(v3),(v4) graph = Graph(GRAPH_ID, self.env.getConnection()) a = Node(properties={"val": 1}) b = Node(properties={"val": 2}) c = Node(properties={"val": 3}) d = Node(properties={"val": 4}) graph.add_node(a) graph.add_node(b) graph.add_node(c) graph.add_node(d) graph.flush() # Find nodes a,b,c such that a.v = 1, a.v = b.v-1 and b.v = c.v-1 q = "MATCH (a {val:1}), (b), (c) WHERE a.val = b.val-1 AND b.val = c.val-1 RETURN a.val, b.val, c.val" plan = graph.execution_plan(q) # Make sure plan contains 2 Value Hash Join operations self.env.assertEquals(plan.count("Value Hash Join"), 2) # Validate results expected_result = [[1, 2, 3]] actual_result = graph.query(q) self.env.assertEquals(actual_result.result_set, expected_result)
def test04_repeated_edges(self): graphname = "repeated_edges" g = Graph(graphname, redis_con) src = Node(label='p', properties={'name': 'src'}) dest = Node(label='p', properties={'name': 'dest'}) edge1 = Edge(src, 'e', dest, properties={'val': 1}) edge2 = Edge(src, 'e', dest, properties={'val': 2}) g.add_node(src) g.add_node(dest) g.add_edge(edge1) g.add_edge(edge2) g.commit() # Verify the new edge q = """MATCH (a)-[e]->(b) RETURN e.val, a.name, b.name ORDER BY e.val""" actual_result = g.query(q) expected_result = [[ edge1.properties['val'], src.properties['name'], dest.properties['name'] ], [ edge2.properties['val'], src.properties['name'], dest.properties['name'] ]] assert (actual_result.result_set == expected_result) # Save RDB & Load from RDB redis_con.execute_command("DEBUG", "RELOAD") # Verify that the latest edge was properly saved and loaded actual_result = g.query(q) assert (actual_result.result_set == expected_result)
def test07_transposed_multi_hop(self): redis_con = self.env.getConnection() g = Graph("tran_multi_hop", redis_con) # (a)-[R]->(b)-[R]->(c)<-[R]-(d)<-[R]-(e) a = Node(properties={"val": 'a'}) b = Node(properties={"val": 'b'}) c = Node(properties={"val": 'c'}) d = Node(properties={"val": 'd'}) e = Node(properties={"val": 'e'}) g.add_node(a) g.add_node(b) g.add_node(c) g.add_node(d) g.add_node(e) ab = Edge(a, "R", b) bc = Edge(b, "R", c) ed = Edge(e, "R", d) dc = Edge(d, "R", c) g.add_edge(ab) g.add_edge(bc) g.add_edge(ed) g.add_edge(dc) g.flush() q = """MATCH (a)-[*2]->(b)<-[*2]-(c) RETURN a.val, b.val, c.val ORDER BY a.val, b.val, c.val""" actual_result = g.query(q) expected_result = [['a', 'c', 'a'], ['a', 'c', 'e'], ['e', 'c', 'a'], ['e', 'c', 'e']] self.env.assertEquals(actual_result.result_set, expected_result)
def create_simple(r: Redis): g = Graph('simple', r) v0 = Node(label='v0', properties={'name': 'v0'}) v1 = Node(label='v1', properties={'name': 'v1'}) v2 = Node(label='v2', properties={'name': 'v2'}) v3 = Node(label='v3', properties={'name': 'v3'}) v4 = Node(label='v4', properties={'name': 'v4'}) g.add_node(v0) g.add_node(v1) g.add_node(v2) g.add_node(v3) g.add_node(v4) e1 = Edge(v0, 'r0', v1, properties={'name': 'r0'}) e2 = Edge(v1, 'r1', v2, properties={'name': 'r1'}) e3 = Edge(v2, 'r0', v3, properties={'name': 'r0'}) e4 = Edge(v3, 'r1', v4, properties={'name': 'r1'}) g.add_edge(e1) g.add_edge(e2) g.add_edge(e3) g.add_edge(e4) g.commit() return g
def test_bi_directional_path_functions(self): node0 = Node(node_id=0, label="L1") node1 = Node(node_id=1, label="L1") node2 = Node(node_id=2, label="L1") edge01 = Edge(node0, "R1", node1, edge_id=0, properties={'value': 1}) edge12 = Edge(node1, "R1", node2, edge_id=1, properties={'value': 2}) redis_graph.add_node(node0) redis_graph.add_node(node1) redis_graph.add_node(node2) redis_graph.add_edge(edge01) redis_graph.add_edge(edge12) redis_graph.flush() # Reverse direction edges which are not part of the graph. Read only values. edge10 = Edge(1, "R1", 0, edge_id=0, properties={'value': 1}) edge21 = Edge(2, "R1", 1, edge_id=1, properties={'value': 2}) expected_results = [[[node0, node1, node0], [edge01, edge10], 2], [[node0, node1, node2, node1], [edge01, edge12, edge21], 3], [[node0, node1, node2, node1, node0], [edge01, edge12, edge21, edge10], 4], [[node1, node2, node1], [edge12, edge21], 2], [[node1, node2, node1, node0], [edge12, edge21, edge10], 3]] query = "MATCH p=(:L1)-[:R1*]->(:L1)<-[:R1*]-() RETURN nodes(p), relationships(p), length(p)" query_info = QueryInfo(query = query, description="Tests path functions over bi directional variable length paths", \ expected_result = expected_results) self._assert_resultset_and_expected_mutually_included( redis_graph.query(query), query_info)
def test_v6_decode(self): graph_name = "v6_rdb_restore" # dump created with the following query (v6 supported property value: integer, double, boolean, string, null, array) # graph.query g "CREATE (:L1 {val:1, strval: 'str', numval: 5.5, nullval: NULL, boolval: true, array: [1,2,3]})-[:E{val:2}]->(:L2{val:3})" # graph.query g "CREATE INDEX ON :L1(val)" # dump g v6_rdb = b"\a\x81\x82\xb6\xa9\x85\xd6\xadh\x06\x05\x02g\x00\x02\x06\x05\x04val\x00\x05\astrval\x00\x05\anumval\x00\x05\bnullval\x00\x05\bboolval\x00\x05\x06array\x00\x02\x02\x02\x00\x05\x03L1\x00\x02\x01\x02\x00\x05\x04val\x00\x02\x01\x05\x03L2\x00\x02\x00\x02\x01\x02\x00\x05\x02E\x00\x02\x00\x02\x02\x02\x01\x02\x00\x02\x06\x05\x04val\x00\x02`\x00\x02\x01\x05\astrval\x00\x02H\x00\x05\x04str\x00\x05\anumval\x00\x02\x80\x00\x00@\x00\x04\x00\x00\x00\x00\x00\x00\x16@\x05\bnullval\x00\x02\x80\x00\x00\x80\x00\x05\bboolval\x00\x02P\x00\x02\x01\x05\x06array\x00\x02\b\x02\x03\x02`\x00\x02\x01\x02`\x00\x02\x02\x02`\x00\x02\x03\x02\x01\x02\x01\x02\x01\x05\x04val\x00\x02`\x00\x02\x03\x02\x01\x02\x00\x02\x01\x02\x00\x02\x01\x05\x04val\x00\x02`\x00\x02\x02\x00\t\x00\xd9\r\xb4c\xf2Z\xd9\xb3" redis_con.restore(graph_name, 0, v6_rdb, True) redis_graph = Graph(graph_name, redis_con) node0 = Node(node_id=0, label='L1', properties={ 'val': 1, 'strval': 'str', 'numval': 5.5, 'boolval': True, 'array': [1, 2, 3] }) node1 = Node(node_id=1, label='L2', properties={'val': 3}) edge01 = Edge(src_node=0, relation='E', dest_node=1, edge_id=0, properties={'val': 2}) results = redis_graph.query("MATCH (n)-[e]->(m) RETURN n, e, m") self.env.assertEqual(results.result_set, [[node0, edge01, node1]]) plan = redis_graph.execution_plan("MATCH (n:L1 {val:1}) RETURN n") self.env.assertIn("Index Scan", plan) results = redis_graph.query("MATCH (n:L1 {val:1}) RETURN n") self.env.assertEqual(results.result_set, [[node0]])
def populate_graph(self, graph_name): # quick return if graph already exists if redis_con.exists(graph_name): return redis_graph people = ["Roi", "Alon", "Ailon", "Boaz", "Tal", "Omri", "Ori"] visits = [("Roi", "USA"), ("Alon", "Israel"), ("Ailon", "Japan"), ("Boaz", "United Kingdom")] countries = ["Israel", "USA", "Japan", "United Kingdom"] redis_graph = Graph(graph_name, redis_con) personNodes = {} countryNodes = {} # create nodes for p in people: person = Node(label="person", properties={ "name": p, "height": random.randint(160, 200) }) redis_graph.add_node(person) personNodes[p] = person for p in countries: country = Node(label="country", properties={ "name": p, "population": random.randint(100, 400) }) redis_graph.add_node(country) countryNodes[p] = country # create edges for v in visits: person = v[0] country = v[1] edge = Edge(personNodes[person], 'visit', countryNodes[country], properties={'purpose': 'pleasure'}) redis_graph.add_edge(edge) redis_graph.commit() # delete nodes, to introduce deleted item within our datablock query = """MATCH (n:person) WHERE n.name = 'Roi' or n.name = 'Ailon' DELETE n""" redis_graph.query(query) query = """MATCH (n:country) WHERE n.name = 'USA' DELETE n""" redis_graph.query(query) # create indices actual_result = redis_con.execute_command( "GRAPH.QUERY", graph_name, "CREATE INDEX ON :person(name, height)") actual_result = redis_con.execute_command( "GRAPH.QUERY", graph_name, "CREATE INDEX ON :country(name, population)") return redis_graph
def populate_graph(cls): redis_graph for v in values: node = Node(label="value", properties={"val": v}) redis_graph.add_node(node) # Add an additional node with no properties redis_graph.add_node(Node(label="value")) redis_graph.commit()
def populate_graph(self): # Populate a graph with two labels, each containing the same property values but different keys. # Each node pair is connected by an edge from label_a to label_b for idx, v in enumerate(values): src = Node(label="label_a", properties={"a_val": v, "a_idx": idx}) dest = Node(label="label_b", properties={"b_val": v, "b_idx": idx}) redis_graph.add_node(src) redis_graph.add_node(dest) edge = Edge(src, 'connects', dest, properties={"edgeval": idx}) redis_graph.add_edge(edge) redis_graph.commit()
def populate_graph(cls): global redis_graph if not redis_con.exists(GRAPH_NAME): # Create entities srcNode = Node(label="L", properties={"name": "SRC"}) destNode = Node(label="L", properties={"name": "DEST"}) redis_graph.add_node(srcNode) redis_graph.add_node(destNode) edge = Edge(srcNode, 'E', destNode) redis_graph.add_edge(edge) redis_graph.commit()
def populate_graph(self): global graph3 a = Node() b = Node() c = Node() graph3.add_node(a) graph3.add_node(b) graph3.add_node(c) graph3.add_edge(Edge(a, "know", b)) graph3.add_edge(Edge(a, "know", b)) graph3.add_edge(Edge(a, "know", c)) graph3.commit()
def model_to_edges(cls, model): """ :type model grapher.models.BaseModel :rtype: list[Edge] """ for (relation, target, properties) in model.get_all_relations(): # Edge(john, 'visited', japan, properties={'purpose': 'pleasure'}) yield Edge(src_node=Node(alias=model.get_node_name()), relation=relation, dest_node=Node(alias=target), properties=cls.encode_properties(properties) if properties else None)
def add_edge(self, start, predicate, end, properties={}): """ Add an edge with the given predicate and properties between start and end nodes. """ logger.debug( f"--adding edge start:{start} pred:{predicate} end:{end} prop:{properties}" ) if isinstance(start, str) and isinstance(end, str): start = Node(node_id=start, label='thing') end = Node(node_id=end, label='thing') self.redis_graph.add_node(start) self.redis_graph.add_node(end) edge = Edge(start, predicate, end, properties) self.redis_graph.add_edge(edge) return edge
def populate_graph(self): graph.query("CALL db.idx.fulltext.createNodeIndex('L1', 'v')") graph.query( "CALL db.idx.fulltext.createNodeIndex({ label: 'L2', stopwords: ['redis', 'world'] }, 'v')" ) a = Node(label="L1", properties={"v": 'hello redis world'}) graph.add_node(a) b = Node(label="L2", properties={"v": 'hello redis world'}) graph.add_node(b) graph.flush()
def test16_assign_entity_properties(self): # repeated merges to the attribute set of a node node = Node(label="L", properties={"v1": 3, "v2": 2}) result = multiple_entity_graph.query( "MATCH (n), (x) WHERE ID(n) = 0 WITH n, x ORDER BY ID(x) SET n += x RETURN n" ) expected_result = [[node], [node]] self.env.assertEqual(result.result_set, expected_result) # validate index updates result = multiple_entity_graph.query( "MATCH (n:L) WHERE n.v1 > 0 RETURN n.v1 ORDER BY n.v1") expected_result = [[3]] self.env.assertEqual(result.result_set, expected_result) result = multiple_entity_graph.query( "MATCH (n:L) WHERE n.v2 > 0 RETURN n.v2 ORDER BY n.v2") expected_result = [[2], [2]] self.env.assertEqual(result.result_set, expected_result) # repeated updates to the attribute set of a node node = Node(label="L", properties={"v2": 2}) result = multiple_entity_graph.query( "MATCH (n), (x) WHERE ID(n) = 0 WITH n, x ORDER BY ID(x) SET n = x RETURN n" ) expected_result = [[node], [node]] self.env.assertEqual(result.result_set, expected_result) # validate index updates result = multiple_entity_graph.query( "MATCH (n:L) WHERE n.v1 > 0 RETURN n.v1 ORDER BY n.v1") expected_result = [] self.env.assertEqual(result.result_set, expected_result) result = multiple_entity_graph.query( "MATCH (n:L) WHERE n.v2 > 0 RETURN n.v2 ORDER BY n.v2") expected_result = [[2], [2]] self.env.assertEqual(result.result_set, expected_result) # repeated multiple updates to the attribute set of a node node = Node(label="L", properties={"v2": 2}) result = multiple_entity_graph.query( "MATCH (n), (x) WHERE ID(n) = 0 WITH n, x ORDER BY ID(x) SET n = x, n += x RETURN n" ) expected_result = [[node], [node]] self.env.assertEqual(result.result_set, expected_result) # validate index updates result = multiple_entity_graph.query( "MATCH (n:L) WHERE n.v1 > 0 RETURN n.v1 ORDER BY n.v1") expected_result = [] self.env.assertEqual(result.result_set, expected_result) result = multiple_entity_graph.query( "MATCH (n:L) WHERE n.v2 > 0 RETURN n.v2 ORDER BY n.v2") expected_result = [[2], [2]] self.env.assertEqual(result.result_set, expected_result)
def test04_test_level_1_nesting_logical_operators_over_path_and_property_filters(self): node0 = Node(node_id=0, label="L") node1 = Node(node_id=1, label="L", properties={'x':1}) edge01 = Edge(src_node=node0, dest_node=node1, relation="R") redis_graph.add_node(node0) redis_graph.add_node(node1) redis_graph.add_edge(edge01) redis_graph.flush() query = "MATCH (n:L) WHERE (n)-[:R]->(:L) OR (n.x=1 AND NOT (n)-[:R]->(:L)) RETURN n" result_set = redis_graph.query(query) expected_results = [[node0],[node1]] query_info = QueryInfo(query = query, description="Tests AND condition with simple filter and negated path filter", expected_result = expected_results) self._assert_resultset_and_expected_mutually_included(result_set, query_info)
def test11_property_map_from_parameter(self): # Overwrite existing properties node = Node(properties={"v2": 10}) result = graph.query( "CYPHER props={v2: 10} MATCH (n) SET n = $props RETURN n") expected_result = [[node]] self.env.assertEqual(result.result_set, expected_result) # Merge property maps node = Node(properties={"v1": True, "v2": 10}) result = graph.query( "CYPHER props={v1: true} MATCH (n) SET n += $props RETURN n") expected_result = [[node]] self.env.assertEqual(result.result_set, expected_result)
def test03_path_filter_or_negated_path_filter(self): node0 = Node(node_id=0, label="L") node1 = Node(node_id=1, label="L", properties={'x':1}) edge01 = Edge(src_node=node0, dest_node=node1, relation="R") redis_graph.add_node(node0) redis_graph.add_node(node1) redis_graph.add_edge(edge01) redis_graph.flush() query = "MATCH (n:L) WHERE (n)-[:R]->(:L) OR NOT (n)-[:R]->(:L) RETURN n" result_set = redis_graph.query(query) expected_results = [[node0],[node1]] query_info = QueryInfo(query = query, description="Tests OR condition with path and negated path filters", expected_result = expected_results) self._assert_resultset_and_expected_mutually_included(result_set, query_info)
def test10_property_map_from_identifier(self): # Overwrite existing properties node = Node(properties={"v2": 10}) result = graph.query( "WITH {v2: 10} as props MATCH (n) SET n = props RETURN n") expected_result = [[node]] self.env.assertEqual(result.result_set, expected_result) # Merge property maps node = Node(properties={"v1": True, "v2": 10}) result = graph.query( "WITH {v1: True} as props MATCH (n) SET n += props RETURN n") expected_result = [[node]] self.env.assertEqual(result.result_set, expected_result)
def test_CRUD_replication(self): # create a simple graph env = self.env source_con = env.getConnection() replica_con = env.getSlaveConnection() # enable write commands on slave, required as all RedisGraph # commands are registered as write commands replica_con.config_set("slave-read-only", "no") # perform CRUD operations # create a simple graph graph = Graph(GRAPH_ID, source_con) replica = Graph(GRAPH_ID, replica_con) s = Node(label='L', properties={'id': 0, 'name': 'a'}) t = Node(label='L', properties={'id': 1, 'name': 'b'}) e = Edge(s, 'R', t) graph.add_node(s) graph.add_node(t) graph.add_edge(e) graph.flush() # create index q = "CREATE INDEX ON :L(id)" graph.query(q) # update entity q = "MATCH (n:L {id:0}) SET n.id = 2, n.name = 'c'" graph.query(q) # delete entity q = "MATCH (n:L {id:1}) DELETE n" graph.query(q) # give replica some time to catch up time.sleep(1) # make sure index is available on replica q = "MATCH (s:L {id:2}) RETURN s.name" plan = graph.execution_plan(q) replica_plan = replica.execution_plan(q) env.assertIn("Index Scan", plan) self.env.assertEquals(replica_plan, plan) # issue query on both source and replica # make sure results are the same result = graph.query(q).result_set replica_result = replica.query(q).result_set self.env.assertEquals(replica_result, result)
def test01_negated_simple_path_filter(self): node0 = Node(node_id=0, label="L") node1 = Node(node_id=1, label="L", properties={'x':1}) edge01 = Edge(src_node=node0, dest_node=node1, relation="R") redis_graph.add_node(node0) redis_graph.add_node(node1) redis_graph.add_edge(edge01) redis_graph.flush() query = "MATCH (n:L) WHERE NOT (n)-[:R]->(:L) RETURN n" result_set = redis_graph.query(query) expected_results = [[node1]] query_info = QueryInfo(query = query, description="Tests simple negated path filter", expected_result = expected_results) self._assert_resultset_equals_expected(result_set, query_info)
def test_node_retrival(self): p0 = Node(node_id=0, label="Person", properties={'name': 'a'}) p1 = Node(node_id=1, label="Person", properties={'name': 'b'}) p2 = Node(node_id=2, label="NoPerson", properties={'name': 'a'}) redis_graph.add_node(p0) redis_graph.add_node(p1) redis_graph.add_node(p2) redis_graph.flush() params = {'name': 'a'} query = "MATCH (n :Person {name:$name}) RETURN n" expected_results = [[p0]] query_info = QueryInfo(query = query, description="Tests expression on param", expected_result = expected_results) self._assert_resultset_equals_expected(redis_graph.query(query, params), query_info)