Filtering#

Filtering subgraphs in subgrounds is done via the where argument in FieldPath. A subgraph's GraphQL provides several options to filter based on nearly any field path.

We will be using curve as the base subgraph for the following examples#
from subgrounds import Subgrounds

sg = Subgrounds()

curve = sg.load_subgraph(
    "https://api.thegraph.com/subgraphs/name/messari/curve-finance-ethereum")

pool = curve.LiquidityPool  # shorthand for examples

Note

In some of the following examples, multiple conditions are stacked on top of each other. This would not result in any data being returned since the multiple conditions would likely conflict with each other.

Matching Values#

Using the == and =! operators in Python, matching exact or negated values on field paths is pretty straight forward:

sg.query_df(
    curve.Query.liquidityPools(
        where=[
            pool.isSingleSided == False,
            # or
            pool.isSingleSided != True,
        ]
    )
)
sg.query_df(
    curve.Query.liquidityPools(
        where={
            "isSingleSided": False,
            # or
            "isSingleSided_not": False,
        }
    )
)

Null Values#

For null values, you can swap values like True and False with None.

sg.query_df(
    curve.Query.liquidityPools(
        where=[
            pool.name == None,
            # or
            pool.name != None,
        ]
    )
)
sg.query_df(
    curve.Query.liquidityPools(
        where={
            "name": None,
            # or
            "name_not": None,
        }
    )
)

Warning

You might be tempted to write pool.name is None which is recommended by linters for checking None values. This is incorrect, as it'll directly return True or False as there is no special generative code for is. You can add # noqa: E711 at the end of these lines to inform your linter to ignore this specific rule as it doesn't apply to this specific operation.

Comparisons#

Filtering can also be based on standard comparison logic on any field path, such as "greater than", "less than", etc — generally more useful for numeric fields.

sg.query_df(
    curve.Query.liquidityPools(
        where=[
            pool.cumulativeVolumeUSD > 150000000,
            pool.cumulativeVolumeUSD >= 150000000,
            pool.cumulativeVolumeUSD < 150000000,
            pool.cumulativeVolumeUSD <= 150000000,
        ]
    )
)
sg.query_df(
    curve.Query.liquidityPools(
        where={
            "cumulativeVolumeUSD_gt": 150000000,
            "cumulativeVolumeUSD_gte": 150000000,
            "cumulativeVolumeUSD_lt": 150000000,
            "cumulativeVolumeUSD_lte": 150000000,
        }
    )
)

Nested Filtering#

Entities can have any layer of nestable objects which thereby are also filterable in the where clause:

sg.query_df(
    curve.Query.liquidityPools(
        where=[
            pool.hourlySnapshots.hourlyVolumeUSD > 1000
        ]
    )
)
sg.query_df(
    curve.Query.liquidityPools(
        where={
            "hourlySnapshots_": {"hourlyVolumeUSD_gt": 14720000}
        }
    )
)

Note

The trailing _ prefix is needed in the GraphQL form since without it, GraphQL assumes you are matching the exact value!