--- title: "Find files" slug: "dev-catalog-guides-find-files" updated: 2026-10-30T18:18:51Z published: 2026-10-30T18:18:51Z canonical: "docs.vastdata.com/dev-catalog-guides-find-files" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.vastdata.com/llms.txt > Use this file to discover all available pages before exploring further. # Find files *Applies to VAST Cluster 5.5.* The Catalog answers "where are the files that…" without walking directories. This guide shows the filters you'll use most: by path, type, age, size, owner and extension, and how to combine them so the cluster does the filtering. Each code block is complete on its own. They read your connection settings from the environment, as in the [quickstart](/develop/docs/dev-catalog-quickstart#before-you-start), and use `CATALOG_PATH` as the subtree to search. ## Filter on the cluster Every example follows the same pattern: - **`search_path`** restricts the query to a subtree. Use it in every query, so the cluster reads only that part of the Catalog. See [search_path](/develop/docs/dev-catalog-concepts-index#searchpath). - **`predicate=`** with filters the SDK can push down: comparisons, `isin`, `between`, `startswith`, `contains` and `isnull`, combined with `&` and `|`. The cluster applies them before it sends any rows. See [pushdowns](/develop/docs/dev-database-reference-pushdowns). - **`columns=`** lists only the columns you'll use. Then sort, count or sum the result in your client. ## By age and size Find files under your path that haven't been modified for 90 days and are larger than 10 MB. This needs at least one such file to return rows: ``` import os from datetime import datetime, timedelta, timezone import pyarrow.compute as pc import vastdb from ibis import _ path = os.environ.get("CATALOG_PATH", "/") cutoff = datetime.now(timezone.utc).replace(tzinfo=None) - timedelta(days=90) session = vastdb.connect() with session.transaction() as tx: rows = tx.catalog().select( columns=["parent_path", "name", "size", "mtime"], predicate=(_.search_path == path) & (_.element_type == "FILE") & (_.mtime < cutoff) & (_.size > 10 * 1024**2), ).read_all() print(rows.num_rows, "files") oldest = rows.sort_by([("mtime", "ascending")]).slice(0, 10) # Catalog times have nanosecond precision, finer than Python's datetime, so format them in Arrow. when = pc.strftime(oldest["mtime"], format="%Y-%m-%d").to_pylist() for row, t in zip(oldest.drop_columns(["mtime"]).to_pylist(), when): print(f"{t} {row['size']:>14,} {row['parent_path']}{row['name']}") ``` ``` 1 files 2026-02-01 26,214,400 /cat-data/archive/2025/sensor-dump.bin ``` The Catalog has four timestamps: `creation_time` (when the element was created), `mtime` (last modification of its data), `ctime` (last change to its metadata) and `atime` (last access). Pick the one that matches your question. Whether `atime` is kept up to date depends on how the view is set up, so check with your platform team before you report on "not accessed since". The timestamps are UTC, although their type carries no time zone, so compare them with UTC times, as the examples do. They have nanosecond precision, which Python's `datetime` can't hold: format them with `pyarrow.compute.strftime` (as above), or cast them, before you convert them to Python values. ## Created recently, by one owner Find files a user created in the last 7 days. Set `CATALOG_OWNER` to a user name that owns files under your path: ``` import os from datetime import datetime, timedelta, timezone import vastdb from ibis import _ path = os.environ.get("CATALOG_PATH", "/") owner = os.environ["CATALOG_OWNER"] since = datetime.now(timezone.utc).replace(tzinfo=None) - timedelta(days=7) session = vastdb.connect() with session.transaction() as tx: rows = tx.catalog().select( columns=["parent_path", "name", "creation_time"], predicate=(_.search_path == path) & (_.element_type == "FILE") & (_.owner_name == owner) & (_.creation_time >= since), ).read_all() print(rows.num_rows, "files created by", owner, "since", since.date()) ``` ``` 23 files created by cat-app since 2026-10-02 ``` `owner_name` is the owner's user name. You can filter on `uid` (POSIX), `owner_sid` (SMB) or `login_name` instead, depending on how the data was written. The [schema reference](/develop/docs/dev-catalog-reference-schema) describes each owner column. ## By extension Find log and CSV files with `isin`, which pushes down as an `OR` of equalities. This needs files with those extensions under your path: ``` import os import vastdb from ibis import _ path = os.environ.get("CATALOG_PATH", "/") session = vastdb.connect() with session.transaction() as tx: rows = tx.catalog().select( columns=["extension", "size"], predicate=(_.search_path == path) & (_.element_type == "FILE") & _.extension.isin(["log", "csv"]), ).read_all() totals = rows.group_by("extension").aggregate([("size", "count"), ("size", "sum")]) for row in totals.to_pylist(): print(f"{row['extension']:<6} {row['size_count']:>8,} files {row['size_sum']:>16,} bytes") ``` ``` csv 5 files 1,465,344 bytes log 5 files 377,856 bytes ``` ## By name and directory `startswith` and `contains` push down on string columns. Find files whose name contains `report` in directories that start with your path: ``` import os import vastdb from ibis import _ path = os.environ.get("CATALOG_PATH", "/") session = vastdb.connect() with session.transaction() as tx: rows = tx.catalog().select( columns=["parent_path", "name"], predicate=(_.search_path == path) & (_.element_type == "FILE") & _.parent_path.startswith(path) & _.name.contains("report"), limit_rows=20, ).read_all() for row in rows.to_pylist(): print(row["parent_path"] + row["name"]) ``` ``` ``` `limit_rows` stops the query after that many rows, which is handy when you only want to see a sample. Which rows you get isn't defined. ## Filters that don't push down Some filters can't be sent to the cluster. The SDK raises `NotImplementedError` showing your expression, rather than filtering in your client without telling you. Common cases with the Catalog: - **A key inside a map column**, such as one tag in `user_tags`. Fetch the map and filter in your client, or ask for a user-defined column. See [tags and metadata](/develop/docs/dev-catalog-guides-tags-and-metadata). - **Arithmetic or functions on a column**, such as `_.size / 1024 > 10`. Rewrite it as a comparison on the column itself: `_.size > 10 * 1024`. - **Comparing two columns**, such as `_.mtime > _.creation_time`. Fetch both and compare in your client. See [rewrite filters that don't push down](/develop/docs/dev-database-guides-querying#rewrite-filters-that-dont-push-down). ## See also - [Capacity reports](/develop/docs/dev-catalog-guides-capacity-reports): sum sizes by owner, extension or directory. - [Catalog schema](/develop/docs/dev-catalog-reference-schema). - [Trino and Spark](/develop/docs/dev-catalog-integrations-trino-and-spark): the same queries in SQL.