OR & NOT operations#

The inherent structure of the query engine works with logical AND operations. However, a complete query engine should also include OR and NOT operations to be able to address all scenarios. For that the methods exclude() and either_or() are included.

def query_edge_either(edge: EdgeOperand) -> None:
    edge.in_group("patient_drug")
    edge.attribute("cost").less_than(200)
    edge.attribute("quantity").equal_to(1)


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


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

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

    return node.index()


medrecord.query_nodes(query_node_either_or)
['pat_3', 'pat_5']
Methods used in the snippet

This includes also “pat_3”, that was not included in the previous section because none of its edges was included in the query_edge_either(), but it can be found in the query_edge_or() now.

def query_node_either_or_component(node: NodeOperand) -> None:
    node.in_group("patient")
    node.attribute("age").greater_than(30)

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


# Exclude query
def query_node_exclude(node: NodeOperand) -> NodeIndicesOperand:
    node.in_group("patient")
    node.exclude(query_node_either_or_component)

    return node.index()


medrecord.query_nodes(query_node_exclude)
['pat_2', 'pat_4', 'pat_1']
Methods used in the snippet
  • in_group() : Query edges that belong to that group.

  • exclude() : Exclude the nodes that belong to the given query.

  • index(): Returns a NodeIndicesOperand representing the indices of the nodes queried.

  • query_nodes() : Retrieves information on the nodes from the MedRecord given the query.

So this gives us all the patient nodes that were not selected with the previous query (logical NOT applied).

1.  Full example Code#

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

from medmodels import MedRecord
from medmodels.medrecord.querying import (
    EdgeIndicesOperand,
    EdgeOperand,
    NodeIndicesOperand,
    NodeOperand,
)

medrecord = MedRecord().from_simple_example_dataset()


def query_edge_either(edge: EdgeOperand) -> None:
    edge.in_group("patient_drug")
    edge.attribute("cost").less_than(200)
    edge.attribute("quantity").equal_to(1)


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


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

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

    return node.index()


medrecord.query_nodes(query_node_either_or)


def query_node_either_or_component(node: NodeOperand) -> None:
    node.in_group("patient")
    node.attribute("age").greater_than(30)

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


# Exclude query
def query_node_exclude(node: NodeOperand) -> NodeIndicesOperand:
    node.in_group("patient")
    node.exclude(query_node_either_or_component)

    return node.index()


medrecord.query_nodes(query_node_exclude)