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 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 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 test14_post_deletion_traversal_directions(self): self.env.flush() redis_con = self.env.getConnection() redis_graph = Graph("G", redis_con) nodes = {} # Create entities. labels = ["Dest", "Src", "Src2"] for idx, l in enumerate(labels): node = Node(label=l, properties={"val": idx}) redis_graph.add_node(node) nodes[l] = node edge = Edge(nodes["Src"], "R", nodes["Dest"]) redis_graph.add_edge(edge) edge = Edge(nodes["Src2"], "R", nodes["Dest"]) redis_graph.add_edge(edge) redis_graph.commit() # Delete a node. query = """MATCH (n:Src2) DELETE n""" actual_result = redis_graph.query(query) self.env.assertEquals(actual_result.nodes_deleted, 1) self.env.assertEquals(actual_result.relationships_deleted, 1) query = """MATCH (n1:Src)-[*]->(n2:Dest) RETURN COUNT(*)""" actual_result = redis_graph.query(query) expected_result = [[1]] self.env.assertEquals(actual_result.result_set, expected_result) # Perform the same traversal, this time traveling from destination to source. query = """MATCH (n1:Src)-[*]->(n2:Dest {val: 0}) RETURN COUNT(*)""" actual_result = redis_graph.query(query) expected_result = [[1]] 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 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 dump_data(n_records): r = redis.Redis(host='localhost', port=6379) data = data_gen(n_records) redis_graph = Graph('file_activity1', r) nodes = {} edges = {} pprint(data) for rec in data: _node = Node(label='file', properties={ 'fid': rec['_id'], 'name': rec['name'], 'date_added': rec['date_added'], 'platform': rec['platform'] }) r.set(rec['_id'], _node.alias) redis_graph.add_node(_node) nodes[rec['_id']] = _node for rec in data: for fileid, time_stamp in rec['downloaded']: edge = Edge(nodes[rec['_id']], 'DOWNLOADED', nodes[fileid], properties={ 'time': time_stamp, 'activity': 'downloaded' }) redis_graph.add_edge(edge) for fileid, time_stamp in rec['executed']: edge = Edge(nodes[rec['_id']], 'EXECUTED', nodes[fileid], properties={ 'time': time_stamp, 'activity': 'executed' }) redis_graph.add_edge(edge) for fileid, time_stamp in rec['removed']: edge = Edge(nodes[rec['_id']], 'REMOVED', nodes[fileid], properties={ 'time': time_stamp, 'activity': 'removed' }) redis_graph.add_edge(edge) redis_graph.commit() print("Graph created")
def setUpClass(cls): print "QueryValidationFlowTest" global redis_graph cls.r = disposable_redis() cls.r.start() redis_con = cls.r.client() # Create a single graph. redis_graph = Graph("G", redis_con) node = Node(properties={"age": 34}) redis_graph.add_node(node) redis_graph.commit()
def empty_graph(): global redis_graph redis_con = _brand_new_redis() redis_graph = Graph("G", redis_con) # Create a graph with a single node. redis_graph.add_node(Node()) redis_graph.commit() # Delete node to have an empty graph. redis_graph.query("MATCH (n) DELETE n")
def populate_graph(cls): global redis_graph redis_con = cls.r.client() redis_graph = Graph(GRAPH_ID, redis_con) # Create entities for i in range(10): node = Node(label="person", properties={"id": i}) redis_graph.add_node(node) redis_graph.commit() # Make sure node id attribute matches node's internal ID. query = """MATCH (n) SET n.id = ID(n)""" redis_graph.query(query)
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 populate_dense_graph(self, dense_graph_name): dense_graph = Graph(dense_graph_name, redis_con) if not redis_con.exists(dense_graph_name): nodes = [] for i in range(10): node = Node(label="n", properties={"val": i}) dense_graph.add_node(node) nodes.append(node) for n_idx, n in enumerate(nodes): for m_idx, m in enumerate(nodes[:n_idx]): dense_graph.add_edge(Edge(n, "connected", m)) dense_graph.flush() return dense_graph
def test_stringify_query_result(self): redis_graph = Graph('stringify', self.r) john = Node(alias='a', label='person', properties={ 'name': 'John Doe', 'age': 33, 'gender': 'male', 'status': 'single' }) redis_graph.add_node(john) japan = Node(alias='b', label='country', properties={'name': 'Japan'}) redis_graph.add_node(japan) edge = Edge(john, 'visited', japan, properties={'purpose': 'pleasure'}) redis_graph.add_edge(edge) self.assertEqual( str(john), """(a:person{age:33,gender:"male",name:"John Doe",status:"single"})""" ) self.assertEqual( str(edge), """(a:person{age:33,gender:"male",name:"John Doe",status:"single"})""" + """-[:visited{purpose:"pleasure"}]->""" + """(b:country{name:"Japan"})""") self.assertEqual(str(japan), """(b:country{name:"Japan"})""") redis_graph.commit() query = """MATCH (p:person)-[v:visited {purpose:"pleasure"}]->(c:country) RETURN p, v, c""" result = redis_graph.query(query) person = result.result_set[0][0] visit = result.result_set[0][1] country = result.result_set[0][2] self.assertEqual( str(person), """(:person{age:33,gender:"male",name:"John Doe",status:"single"})""" ) self.assertEqual(str(visit), """()-[:visited{purpose:"pleasure"}]->()""") self.assertEqual(str(country), """(:country{name:"Japan"})""") redis_graph.delete()
def test00_test_data_valid_after_rename(self): global graph node0 = Node(node_id=0, label="L", properties={'name':'x', 'age':1}) graph.add_node(node0) graph.flush() redis_con.rename(GRAPH_ID, NEW_GRAPH_ID) graph = Graph(NEW_GRAPH_ID, redis_con) node1 = Node(node_id=0, label="L", properties={'name':'x', 'age':1}) graph.add_node(node1) graph.flush() query = "MATCH (n) return n" expected_results = [[node0], [node1]] query_info = QueryInfo(query = query, description="Tests data is valid after renaming", expected_result = expected_results) self._assert_resultset_and_expected_mutually_included(graph.query(query), query_info)
def test13_delete_path_elements(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() # Delete projected # Unwind path nodes. query = """MATCH p = (src)-[e]->(dest) WITH nodes(p)[0] AS node, relationships(p)[0] as edge DELETE node, edge""" actual_result = redis_graph.query(query) self.env.assertEquals(actual_result.nodes_deleted, 1) self.env.assertEquals(actual_result.relationships_deleted, 1)
def populate_acyclic_graph(self): global acyclic_graph acyclic_graph = Graph("G", redis_con) # Construct a graph with the form: # (v1)-[:E]->(v2)-[:E]->(v3) node_props = ['v1', 'v2', 'v3'] nodes = [] for idx, v in enumerate(node_props): node = Node(label="L", properties={"val": v}) nodes.append(node) acyclic_graph.add_node(node) edge = Edge(nodes[0], "E", nodes[1]) acyclic_graph.add_edge(edge) edge = Edge(nodes[1], "E", nodes[2]) acyclic_graph.add_edge(edge) acyclic_graph.commit()
def test_graph_creation(self): redis_graph = Graph('social', self.r) john = Node(label='person', properties={ 'name': 'John Doe', 'age': 33, 'gender': 'male', 'status': 'single' }) redis_graph.add_node(john) japan = Node(label='country', properties={'name': 'Japan'}) redis_graph.add_node(japan) edge = Edge(john, 'visited', japan, properties={'purpose': 'pleasure'}) redis_graph.add_edge(edge) redis_graph.commit() query = ( 'MATCH (p:person)-[v:visited {purpose:"pleasure"}]->(c:country) ' 'RETURN p, v, c') result = redis_graph.query(query) person = result.result_set[0][0] visit = result.result_set[0][1] country = result.result_set[0][2] self.assertEqual(person, john) self.assertEqual(visit.properties, edge.properties) self.assertEqual(country, japan) query = """RETURN [1, 2.3, "4", true, false, null]""" result = redis_graph.query(query) self.assertEqual([1, 2.3, "4", True, False, None], result.result_set[0][0]) # All done, remove graph. redis_graph.delete()
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 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_optional_match(self): redis_graph = Graph('optional', self.r) # Build a graph of form (a)-[R]->(b) node0 = Node(node_id=0, label="L1", properties={'value': 'a'}) node1 = Node(node_id=1, label="L1", properties={'value': 'b'}) edge01 = Edge(node0, "R", node1, edge_id=0) redis_graph.add_node(node0) redis_graph.add_node(node1) redis_graph.add_edge(edge01) redis_graph.flush() # Issue a query that collects all outgoing edges from both nodes (the second has none). query = """MATCH (a) OPTIONAL MATCH (a)-[e]->(b) RETURN a, e, b ORDER BY a.value""" expected_results = [[node0, edge01, node1], [node1, None, None]] result = redis_graph.query(query) self.assertEqual(expected_results, result.result_set) redis_graph.delete()
def test_path(self): redis_graph = Graph('social', self.r) node0 = Node(node_id=0, label="L1") node1 = Node(node_id=1, label="L1") edge01 = Edge(node0, "R1", node1, edge_id=0, properties={'value': 1}) redis_graph.add_node(node0) redis_graph.add_node(node1) redis_graph.add_edge(edge01) redis_graph.flush() path01 = Path.new_empty_path().add_node(node0).add_edge( edge01).add_node(node1) expected_results = [[path01]] query = "MATCH p=(:L1)-[:R1]->(:L1) RETURN p ORDER BY p" result = redis_graph.query(query) self.assertEqual(expected_results, result.result_set) # All done, remove graph. redis_graph.delete()
def test04_repeated_edges(self): graph_names = ["repeated_edges", "{tag}_repeated_edges"] for graph_name in graph_names: graph = Graph(graph_name, 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}) graph.add_node(src) graph.add_node(dest) graph.add_edge(edge1) graph.add_edge(edge2) graph.flush() # Verify the new edge q = """MATCH (a)-[e]->(b) RETURN e.val, a.name, b.name ORDER BY e.val""" actual_result = graph.query(q) expected_result = [[ edge1.properties['val'], src.properties['name'], dest.properties['name'] ], [ edge2.properties['val'], src.properties['name'], dest.properties['name'] ]] self.env.assertEquals(actual_result.result_set, expected_result) # Save RDB & Load from RDB self.env.dumpAndReload() # Verify that the latest edge was properly saved and loaded actual_result = graph.query(q) self.env.assertEquals(actual_result.result_set, expected_result)
def test07_index_scan_and_id(self): redis_con = self.env.getConnection() redis_graph = Graph("G", redis_con) nodes = [] for i in range(10): node = Node(node_id=i, label='person', properties={'age': i}) nodes.append(node) redis_graph.add_node(node) redis_graph.flush() query = """CREATE INDEX ON :person(age)""" query_result = redis_graph.query(query) self.env.assertEqual(1, query_result.indices_created) query = """MATCH (n:person) WHERE id(n)>=7 AND n.age<9 RETURN n ORDER BY n.age""" plan = redis_graph.execution_plan(query) query_result = redis_graph.query(query) self.env.assertIn('Index Scan', plan) self.env.assertIn('Filter', plan) query_result = redis_graph.query(query) self.env.assertEqual(2, len(query_result.result_set)) expected_result = [[nodes[7]], [nodes[8]]] self.env.assertEquals(expected_result, query_result.result_set)
def populate_cyclic_graph(self): global graph_with_cycle graph_with_cycle = Graph("H", redis_con) # Construct a graph with the form: # (v1)-[:E]->(v2)-[:E]->(v3), (v2)-[:E]->(v1) node_props = ['v1', 'v2', 'v3'] nodes = [] for idx, v in enumerate(node_props): node = Node(label="L", properties={"val": v}) nodes.append(node) graph_with_cycle.add_node(node) edge = Edge(nodes[0], "E", nodes[1]) graph_with_cycle.add_edge(edge) edge = Edge(nodes[1], "E", nodes[2]) graph_with_cycle.add_edge(edge) # Introduce a cycle between v2 and v1. edge = Edge(nodes[1], "E", nodes[0]) graph_with_cycle.add_edge(edge) graph_with_cycle.commit()
def test12_delete_unwind_entity(self): redis_con = self.env.getConnection() redis_graph = Graph("delete_test", redis_con) # Create 10 nodes. for i in range(10): redis_graph.add_node(Node()) redis_graph.flush() # Unwind path nodes. query = """MATCH p = () UNWIND nodes(p) AS node DELETE node""" actual_result = redis_graph.query(query) self.env.assertEquals(actual_result.nodes_deleted, 10) self.env.assertEquals(actual_result.relationships_deleted, 0) for i in range(10): redis_graph.add_node(Node()) redis_graph.flush() # Unwind collected nodes. query = """MATCH (n) WITH collect(n) AS nodes UNWIND nodes AS node DELETE node""" actual_result = redis_graph.query(query) self.env.assertEquals(actual_result.nodes_deleted, 10) self.env.assertEquals(actual_result.relationships_deleted, 0)
def test(): r = redis.Redis(host='localhost', port=6379) redis_graph = Graph('social', r) john = Node(label='person', properties={ 'name': 'John Doe', 'age': 33, 'gender': 'male', 'status': 'single' }) redis_graph.add_node(john) japan = Node(label='country', properties={'name': 'Japan'}) redis_graph.add_node(japan) edge = Edge(john, 'visited', japan, properties={'purpose': 'pleasure'}) redis_graph.add_edge(edge) redis_graph.commit() query = """MATCH (p:person)-[v:visited {purpose:"pleasure"}]->(c:country) RETURN p.name, p.age, v.purpose, c.name""" result = redis_graph.query(query) # Print resultset result.pretty_print() # Iterate through resultset, skip header row at position 0 for record in result.result_set[1:]: person_name = record[0] person_age = record[1] visit_purpose = record[2] country_name = record[3]
def create_friends(r: Redis): g = Graph('friends', r) adam = Node(label='User', properties={'name': 'Adam', 'mail': 'f****r'}) pernilla = Node(label='User', properties={'name': 'Pernilla'}) david = Node(label='User', properties={'name': 'David'}) g.add_node(adam) g.add_node(pernilla) g.add_node(david) g.add_edge(Edge(adam, 'FRIEND', pernilla)) g.add_edge(Edge(pernilla, 'FRIEND', david)) g.commit() return g
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': 'abcd'}) t = Node(label='L', properties={'id': 1, 'name': 'efgh'}) 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) # create full-text index q = "CALL db.idx.fulltext.createNodeIndex('L', 'name')" graph.query(q) # add fields to existing index q = "CALL db.idx.fulltext.createNodeIndex('L', 'title', 'desc')" graph.query(q) # create full-text index with index config q = "CALL db.idx.fulltext.createNodeIndex({label: 'L1', language: 'german', stopwords: ['a', 'b'] }, 'title', 'desc')" graph.query(q) # update entity q = "MATCH (n:L {id:1}) SET n.id = 2" graph.query(q) # delete entity q = "MATCH (n:L {id:0}) 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) # make sure node count on both primary and replica is the same q = "MATCH (n) RETURN count(n)" result = graph.query(q).result_set replica_result = replica.query(q).result_set self.env.assertEquals(replica_result, result) # make sure nodes are in sync q = "MATCH (n) RETURN n ORDER BY n" result = graph.query(q).result_set replica_result = replica.query(q).result_set self.env.assertEquals(replica_result, result) # make sure both primary and replica have the same set of indexes q = "CALL db.indexes()" result = graph.query(q).result_set replica_result = replica.query(q).result_set self.env.assertEquals(replica_result, result) # drop fulltext index q = "CALL db.idx.fulltext.drop('L')" graph.query(q) # give replica some time to catch up time.sleep(1) # make sure both primary and replica have the same set of indexes q = "CALL db.indexes()" result = graph.query(q).result_set replica_result = replica.query(q).result_set self.env.assertEquals(replica_result, result)
redis_graph.query("CREATE INDEX ON :word(value)") redis_graph.call_procedure("db.idx.fulltext.createNodeIndex", 'word', 'value') # Populate graph. with open("./data/words_alpha.txt") as file: content = file.read() words = content.split() words = [w.lower() for w in words if len(w) > 1] unique_words = set(words) max_node_count = len(unique_words) node_count = 0 with progressbar.ProgressBar(max_value=max_node_count) as bar: for word in unique_words: n = Node(label='word', properties={'value': word}) redis_graph.add_node(n) node_count += 1 bar.update(node_count) if (node_count % 100) == 0: redis_graph.flush() # Flush left-overs. redis_graph.flush() with open("./data/TwitterConvCorpus.txt") as file: content = file.read() for c in REMOVE_CHARS: content = content.replace(c, ' ') words = content.split() words = [w.lower() for w in words if len(w) > 1]