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
in_group()
: Query edges that belong to that group.attribute()
: Returns aEdgeMultipleValuesWithIndexOperand()
to query on the values of the edges for that attribute.less_than()
: Query values that are less than that value.equal_to()
: Query values that are equal to that value.in_group()
: Query nodes that belong to that group.attribute()
: Returns aNodeMultipleValuesWithIndexOperand()
to query on the values of the nodes for that attribute.greater_than()
: Query values that are greater than that value.edges()
: Returns aEdgeOperand()
to query on the edges of those nodes.either_or()
: Queries edges that match either one or the other given queries.index()
: Returns aNodeIndicesOperand
representing the indices of the nodes queried.query_nodes()
: Retrieves information on the nodes from the MedRecord given the query.
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 aNodeIndicesOperand
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)