Queries as Function Arguments#

In all other sections, we have used queries with the method query_nodes() for representation purposes of its capacities. However, queries can also be used as function arguments to other methods or indexers from the GraphRecord that take edge/node indices or the queries that result on those indices as arguments. Here are some examples of those functions:

  • Using the add_group() to create groups in the GraphRecord out of a chosen subset of users. We need to unfreeze_schema() first, since this new group does not exist in the schema and we have a provided schema in the example dataset.

# Node queries as function arguments
graphrecord.unfreeze_schema()
graphrecord.add_group("old_male_user", nodes=query_node_user_older_than_30)
graphrecord.groups
['user', 'user_product', 'product', 'old_male_user']
  • Using the node[] indexer, which retrieves the attributes for the given node indices.

graphrecord.node[query_node_either_or]
{'pat_2': {'age': 40, 'gender': 'M'}, 'pat_3': {'age': 50, 'gender': 'F'}, 'pat_4': {'gender': 'M', 'age': 60}}
  • Using groups_of_node(), a method that retrieves the groups to which a specific node index belongs to.

graphrecord.groups_of_node(query_node_user_older_than_30)
{'pat_2': ['user'], 'pat_3': ['user'], 'pat_4': ['user']}
  • Using edge_endpoints(), a method that retrieves the source and target nodes of the specified edge(s) in the GraphRecord.

graphrecord.edge_endpoints(query_edge_old_user_cheap_item)
{}
Methods used in the snippet
  • unfreeze_schema() : Unfreezes the schema. Changes are automatically inferred.

  • add_group() : Adds a group to the GraphRecord, optionally with node and edge indices.

  • groups : Lists the groups in the GraphRecord instance.

  • node[] : Provides access to node information within the GraphRecord instance via an indexer, returning a dictionary with node indices as keys and node attributes as values.

  • groups_of_node() : Retrieves the groups associated with the specified node(s) in the GraphRecord.

  • edge_endpoints() : Retrieves the source and target nodes of the specified edge(s) in the GraphRecord.

1.  Full example Code#

The full code examples for this chapter can be found here:

import pandas as pd

import graphrecords as gr
from graphrecords.querying import (
    EdgeIndicesOperand,
    EdgeOperand,
    NodeIndicesOperand,
    NodeOperand,
)

# Create example dataset manually
users = pd.DataFrame(
    [
        ["pat_0", 20, "M"],
        ["pat_1", 30, "F"],
        ["pat_2", 40, "M"],
        ["pat_3", 50, "F"],
        ["pat_4", 60, "M"],
    ],
    columns=["index", "age", "gender"],
)

products = pd.DataFrame(
    [
        ["drug_0", "fentanyl injection"],
        ["drug_1", "aspirin tablet"],
        ["drug_2", "insulin pen"],
    ],
    columns=["index", "description"],
)

user_product = pd.DataFrame(
    [
        ["pat_0", "drug_0", 100, 1, "2020-01-01"],
        ["pat_1", "drug_0", 150, 2, "2020-02-15"],
        ["pat_1", "drug_1", 50, 1, "2020-03-10"],
        ["pat_2", "drug_1", 75, 12, "2020-04-20"],
        ["pat_2", "drug_2", 200, 1, "2020-05-05"],
        ["pat_3", "drug_2", 180, 12, "2020-06-30"],
        ["pat_4", "drug_0", 120, 1, "2020-07-15"],
        ["pat_4", "drug_1", 60, 2, "2020-08-01"],
    ],
    columns=["source", "target", "cost", "quantity", "time"],
)

graphrecord = (
    gr.GraphRecord.builder()
    .add_nodes((users, "index"), group="user")
    .add_nodes((products, "index"), group="product")
    .add_edges((user_product, "source", "target"), group="user_product")
    .build()
)


# Intermediate node query
def query_node_user_older_than_30(node: NodeOperand) -> NodeIndicesOperand:
    node.in_group("user")
    node.index().contains("pat")

    node.has_attribute("age")
    node.attribute("age").greater_than(30)

    return node.index()


# Either/or query
def query_edge_either(edge: EdgeOperand) -> None:
    edge.in_group("user_product")
    edge.attribute("cost").less_than(200)
    edge.attribute("quantity").equal_to(1)


def query_edge_or(edge: EdgeOperand) -> None:
    edge.in_group("user_product")
    edge.attribute("cost").less_than(200)
    edge.attribute("quantity").equal_to(12)


def query_node_either_or(node: NodeOperand) -> NodeIndicesOperand:
    node.in_group("user")
    node.attribute("age").greater_than(30)

    node.edges().either_or(query_edge_either, query_edge_or)

    return node.index()


# Advanced edge query
def query_edge_old_user_cheap_item(edge: EdgeOperand) -> EdgeIndicesOperand:
    edge.in_group("user_product")
    edge.attribute("cost").less_than(200)

    edge.source_node().attribute("age").is_max()
    edge.target_node().attribute("description").contains("insulin")
    return edge.index()


# Node queries as function arguments
graphrecord.unfreeze_schema()
graphrecord.add_group("old_male_user", nodes=query_node_user_older_than_30)
graphrecord.groups

graphrecord.node[query_node_either_or]
graphrecord.groups_of_node(query_node_user_older_than_30)
graphrecord.edge_endpoints(query_edge_old_user_cheap_item)