Skip to content

Property queries

As you will have seen in the ingestion tutorial, graphs, nodes and edges may all have constant and temporal properties, consisting of a wide range of data types. Raphtory provides a unified API for accessing this data via the Properties object available on all classes by calling .properties.

This Properties class offers several functions for you to access the values you are interested in in the most appropriate format. To demonstrate this let's create a simple graph with one node that has a variety of different properties, both temporal and constant.

We can grab this nodes property object and call all of the functions to access the data:

  • keys(): Returns all of the property keys (names).
  • values(): Returns the latest value for each property.
  • items(): Combines the keys() and values() into a list of tuples.
  • get(): Returns the latest value for a given key if the property exists or None if it does not.
  • as_dict(): Converts the Properties object into a standard python dictionary.

Node

from raphtory import Graph

property_g = Graph()
# Create the node and add a variety of temporal properties
v = property_g.add_node(
    timestamp=1,
    id="User",
    properties={"count": 1, "greeting": "hi", "encrypted": True},
)
property_g.add_node(
    timestamp=2,
    id="User",
    properties={"count": 2, "balance": 0.6, "encrypted": False},
)
property_g.add_node(
    timestamp=3,
    id="User",
    properties={"balance": 0.9, "greeting": "hello", "encrypted": True},
)
# Add some constant properties
v.add_constant_properties(
    properties={
        "inner data": {"name": "bob", "value list": [1, 2, 3]},
        "favourite greetings": ["hi", "hello", "howdy"],
    },
)
# Call all of the functions on the properties object
properties = v.properties
print("Property keys:", properties.keys())
print("Property values:", properties.values())
print("Property tuples:", properties.items())
print("Latest value of balance:", properties.get("balance"))
print("Property keys:", properties.as_dict(), "\n")

# Access the keys of the constant and temporal properties individually
constant_properties = properties.constant
temporal_properties = properties.temporal
print("Constant property keys:", constant_properties.keys())
print("Constant property keys:", temporal_properties.keys())

Output

Property keys: ['count', 'greeting', 'encrypted', 'balance', 'inner data', 'favourite greetings']
Property values: [2]
Property tuples: [('count', 2), ('greeting', 'hello'), ('encrypted', True), ('balance', 0.9), ('inner data', {'value list': [1, 2, 3], 'name': 'bob'}), ('favourite greetings', ['hi', 'hello', 'howdy'])]
Latest value of balance: 0.9
Property keys: {'inner data': {'value list': [1, 2, 3], 'name': 'bob'}, 'greeting': 'hello', 'favourite greetings': ['hi', 'hello', 'howdy'], 'balance': 0.9, 'encrypted': True, 'count': 2} 

Constant property keys: ['inner data', 'favourite greetings']
Constant property keys: ['count', 'greeting', 'encrypted', 'balance']

The Properties class also has two attributes constant and temporal which have all of the above functions, but are restricted to only the properties which fall within their respective catagories.

Info

The semantics for ConstProperties are exactly the same as described above. TemporalProperties on the other hand allow you to do much more, as is discussed below.

Temporal specific functions

As temporal properties have a history, we may often want to do more than just look at the latest value. As such, calling get(), values() or items() on TemporalProperties will return a TemporalProp object which contains all of the value history.

TemporalProp has a host of helper functions covering anything that you may want to do with this history. This includes:

  • value()/values(): Get the latest value or all values of the property.
  • at(): Get the latest value of the property at the specified time.
  • history()/history_date_time(): Get the timestamps of all updates to the property.
  • items()/items_date_time(): Merges values() and history()/history_date_time() into a list of tuples.
  • mean()/median()/average(): If the property is orderable, get the average value for the property.
  • min()/max(): If the property is orderable, get the minimum or maximum value.
  • count(): Get the number of updates which have occurred
  • sum(): If the property is additive, sum the values and return the result.

In the code below, we call a subset of these functions on the Weight property of the edge between FELIPE and MAKO in our monkey graph.

Edge

properties = g.edge("FELIPE", "MAKO").properties.temporal
print("Property keys:", properties.keys())
weight_prop = properties.get("Weight")
print("Weight property history:", weight_prop.items())
print("Average interaction weight:", weight_prop.mean())
print("Total interactions:", weight_prop.count())
print("Total interaction weight:", weight_prop.sum())

Output

Property keys: ['Weight']
Weight property history: [(1560437400000, 1), (1560437640000, 1), (1560935460000, 1), (1561043280000, 0), (1561043280000, 1), (1561043340000, 1), (1561117620000, 1), (1561373880000, 1), (1561373880000, 1), (1561373940000, 1), (1561373940000, 0), (1561373940000, 1), (1561373940000, 1), (1561373940000, 1), (1561390860000, 1), (1561390860000, 1), (1561390860000, 1), (1561390920000, 1), (1561643580000, 1), (1561717080000, 1), (1561717140000, 1), (1561970760000, 1), (1562148960000, 1), (1562148960000, 1), (1562149020000, 1), (1562149020000, 1), (1562149080000, 1), (1562671020000, 1)]
Average interaction weight: 0.9285714285714286
Total interactions: 28
Total interaction weight: 26