🚧 This website is still under construction. Please stay tuned. 🚧
Developers
API
Graph Retrieval

Cypher Query

This section covers some specifics on how the Graph is structured and returned to the end user.

Buyer Query Structure

MATCH (o:Organization)<-[e:hasBuyer]-(n:Release)-[e2:hasContracts|:hasAwards|:hasTender]->(n2)-[e3*0..2]-(o3:Organization)
WHERE o.id = $id AND n.date >= '{start_date}' AND n.date < '{end_date}'
OPTIONAL MATCH (o)-[i:isSameAs]->(o2:Organization)
WHERE i.probability > {match_probability}
RETURN o, e, n, e2, n2, i, o2, e3, o3 SKIP {skip} LIMIT {limit}

Components Explained

Primary Match Criteria:

  • Identifies a Release where 'o' is a buyer Organization.
   (o:Organization)<-[e:hasBuyer]-(n:Release)
  • Connects Release to an entity 'n2' (e.g. Contract, Award, or Tender).
   (n)-[e2:hasContracts|:hasAwards|:hasTender]->(n2)
  • Optionally connects 'n2' to another organization 'o3' via up to two intermediate relationships or nodes, allowing for secondary or indirect relationships.
   (n2)-[e3*0..2]-(o3:Organization)

Filtering Conditions:

  • Filters are applied to ensure that only data matching the given organization ID and within the specified date range is considered.
  • An additional filter applies to the optional matching of organization aliases based on a probability threshold.

Optional Match:

  • Attempts to identify and include any potential duplicate or synonymous organizations to 'o' (designated as 'o2'), provided the match probability exceeds a specified threshold.

Return Statement:

  • The query returns the following elements:
    • o, o2 (Organizations): The primary organization and any potentially matched synonymous organization.
    • e (hasBuyer Relationship): The relationship showing the organization as the buyer of a release.
    • n (Release): The procurement release node.
    • e2 (Transaction Relationships): Relationships indicating the type of transaction (contract, award, or tender).
    • n2 (Transaction Entity): The node representing the transaction.
    • i (isSameAs Relationship): The relationship, if any, indicating that 'o' is the same as 'o2'.
    • e3 (Intermediate Relationships): Any relationships connecting 'n2' to 'o3'.
    • o3 (Secondary Organizations): Other organizations potentially connected to the transaction indirectly.

Pagination:

  • SKIP {skip} and LIMIT {limit} control the pagination of the results, allowing developers to fetch data in manageable chunks.

Supplier Query Structure

Primary Match Criteria

  • Identifies a Release that has Award(s) that are related to supplier Organization 'supplierOrg'.
   (supplierOrg:Organization)<-[supplierRel:hasSuppliers]-(awardNode:Award)<-[awardRel:hasAwards]-(releaseNode:Release)
  • Connects Release to an entity 'transactionNode' (e.g. Contract, Award, or Tender).
   (releaseNode:Release)-[transactionRel:hasContracts|hasAwards|hasTender]->(transactionNode)
  • Optionally connects 'transactionNode' to another organization 'relatedOrg' through up to two intermediate relationships or nodes, allowing for secondary or indirect relationships.
   (transactionNode)-[orgRel*0..2]-(relatedOrg:Organization)

Other Sections

  • Other sections are the same as the buyer query, so please refer back to buyer query.

Graph Endpoint Function

The Graph function has multiple parameters that allow users to:

  • get graph based on Organizations ID
  • filter results by date
  • limit the size of the returned results
  • skip certain number of results they want returned
async def get_organization_graph(
    id: uuid.UUID,
    start_date: datetime.date = None,
    end_date: datetime.date = None,
    match_probability: float = 0.75,
    limit: int = 400,
    skip: int = 0,
    ...,
):

In a case where a user doesn't provide a specific start and end date, the function sets 'end_date' to today and 'start_date' to a date one year before today.

    if end_date is None:
        end_date = datetime.date.today()

    if start_date is None:
        start_date = datetime.date(end_date.year - 1, end_date.month, end_date.day)

The function then retrieves the organization based on provided ID, and saves it to a variable. That variable is later used to allow the function to select if the supplier or buyer query needs to be executed.

    # Find out whether the organization is a buyer or a supplier
    organization = await get_organization(id, conn)
...
...
    if "buyer" in organization.roles ...
    elif organization.roles == "supplier": ...

Results of the query are then processed to OCDSGraph and an OCDSGraph is returned by the function.