예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
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
예제 #4
0
    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)
예제 #5
0
    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)
예제 #7
0
    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)
예제 #8
0
    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)
예제 #9
0
    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)
예제 #10
0
    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)
예제 #11
0
    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)
예제 #12
0
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
예제 #13
0
    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)
예제 #14
0
 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]])
예제 #15
0
    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
예제 #16
0
    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()
예제 #17
0
 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()
예제 #18
0
 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()
예제 #19
0
 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()
예제 #20
0
 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)
예제 #21
0
 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
예제 #22
0
    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()
예제 #23
0
    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)
예제 #24
0
    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)
예제 #25
0
    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)
예제 #26
0
    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)
예제 #27
0
    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)
예제 #28
0
    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)
예제 #29
0
    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)
예제 #30
0
    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)