> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meshagent.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Datasets

## Overview

The `DatasetsClient` is the Room API for room-scoped structured data. Use it to create tables, insert and update rows, build indexes, and run text or vector search without provisioning a separate dataset.

Datasets are designed and optimized for batch writes, indexing, scans, search, and retrieval. They are not a transactional database replacement: avoid using them for high-frequency row-by-row mutations, cross-table transactions, locks, or workloads that require immediate transactional consistency.

## CLI commands

Start with the CLI help, then use a few common commands:

```bash bash theme={null}
meshagent room dataset --help
meshagent room dataset table --room myroom
meshagent room dataset inspect --room myroom --table users
meshagent room dataset search --room myroom --table users
```

## Why use the Datasets API?

* Keep structured room data close to the agents and services that use it.
* Support filtering, analytics, semantic search, and retrieval workflows in one place.
* Manage schemas and indexes through the same Room API surface you already use for messaging, storage, and sync.

## How it works

Each room dataset contains named tables. You can create tables from a schema or from raw data, update rows, create scalar/full-text/vector indexes, and run searches that combine filters with text or vector similarity. Use it when your room needs structured records instead of only files or chat history.

> Current implementation: MeshAgent room dataset is currently backed directly by Lance datasets, which provide the table, vector, and full-text primitives used by the room dataset toolkit.

> Typed values: MeshAgent also supports `json`, `uuid`, `list`, and `struct` dataset types. In the typed SDKs, use the wrapper classes for those values, such as `DatasetJson`, `DatasetStruct`, `DatasetUuid` / `UuidValue`, and `DatasetExpression` where the client requires them.

## Permissions and grants

The Datasets API is controlled by the `dataset` grant on the participant token.

In practice:

* `list_tables` controls whether the participant can list tables
* table grants control `read`, `write`, and `alter` access per table
* if no table list is supplied, access is broad across the room dataset

See [API Scopes](../rest_api/api_scopes) and [Service YAML](../services/deployment/deploy_services).

## API reference

Use the methods below to manage room tables, rows, indexes, and search workflows. Most methods are asynchronous calls that you `await`; streaming helpers such as `sql_stream()`, `search_stream()`, and `watch_table()` return async iterators that you consume with `async for`.

### Python SDK signatures

The examples below focus on common cross-SDK workflows. The Python SDK also exposes namespace, branch, version, streaming, SQL, and maintenance helpers directly on `room.datasets`:

```python Python theme={null}
await room.datasets.list_tables(namespace=None, branch=None)
await room.datasets.inspect(table="users", namespace=None, branch=None, version=None)

await room.datasets.create_table_with_schema(
    name="users", schema=None, data=None, mode="create",
    namespace=None, branch=None, metadata=None,
)
await room.datasets.create_table_from_data(
    name="users", data=None, mode="create",
    namespace=None, branch=None, metadata=None,
)
await room.datasets.create_table_from_data_stream(
    name="users", chunks=chunks, schema=None, mode="create",
    namespace=None, branch=None, metadata=None,
)
await room.datasets.create_table_from_json_data(
    name="users", data=None, mode="create",
    namespace=None, branch=None, metadata=None,
)

await room.datasets.drop_table(name="users", ignore_missing=False, namespace=None, branch=None)
await room.datasets.rename_table(name="users", new_name="customers", namespace=None, branch=None)
await room.datasets.add_columns(table="users", new_columns={"active": "true"}, namespace=None, branch=None)
await room.datasets.drop_columns(table="users", columns=["active"], namespace=None, branch=None)

await room.datasets.insert(table="users", records=records, namespace=None, branch=None)
await room.datasets.insert_stream(table="users", chunks=chunks, namespace=None, branch=None)
await room.datasets.update(table="users", where="id = 1", values={"email": "alice@example.com"}, namespace=None, branch=None)
await room.datasets.delete(table="users", where="id = 1", namespace=None, branch=None)
await room.datasets.merge(table="users", on="id", records=records, namespace=None, branch=None)
await room.datasets.merge_stream(table="users", on="id", chunks=chunks, namespace=None, branch=None)

rows = await room.datasets.sql(query="select * from users", tables=None, params=None, namespace=None, branch=None)
opened = await room.datasets.open_sql_query(query="select * from users", tables=None, params=None, namespace=None, branch=None)
result = await room.datasets.execute_sql(query="select * from users", tables=None, params=None, namespace=None, branch=None)
async for batch in room.datasets.sql_stream(query="select * from users", tables=None, params=None, namespace=None, branch=None):
    ...
async for batch in room.datasets.read_sql_query(query_id=opened.query_id):
    ...
await room.datasets.close_sql_query(query_id=opened.query_id)
await room.datasets.cancel_sql_query(query_id=opened.query_id)
rows_affected = await room.datasets.execute_sql_statement(query="delete from users where active = false", tables=None, params=None, namespace=None, branch=None)

rows = await room.datasets.search(
    table="users", text=None, vector=None, where=None, offset=None, limit=None,
    select=None, namespace=None, branch=None, version=None,
)
async for batch in room.datasets.search_stream(
    table="users", text=None, vector=None, where=None, offset=None, limit=None,
    select=None, namespace=None, branch=None, version=None,
):
    ...
async for event in room.datasets.watch_table(table="users", namespace=None, branch=None, poll_interval_seconds=0.5):
    ...
count = await room.datasets.count(table="users", text=None, vector=None, where=None, namespace=None, branch=None, version=None)

await room.datasets.optimize(table="users", namespace=None, branch=None, config=None)
stats = await room.datasets.stats(table="users", namespace=None, branch=None, version=None, max_rows_per_group=None)
await room.datasets.restore(table="users", version=12, namespace=None, branch=None)
versions = await room.datasets.list_versions(table="users", namespace=None, branch=None)

await room.datasets.create_index(table="users", config=index_config, namespace=None, branch=None)
await room.datasets.drop_index(table="users", name="users_email_idx", namespace=None, branch=None)
indexes = await room.datasets.list_indexes(table="users", namespace=None, branch=None, version=None)

branches = await room.datasets.list_branches(namespace=None)
await room.datasets.create_branch(branch="exp", from_branch=None, namespace=None)
await room.datasets.delete_branch(branch="exp", namespace=None)
```

### `list_tables()`

**Description**
Retrieves a list of all table names currently present in the dataset.

**Returns**:

* A promise that resolves to an array of table name strings.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset table \
    --room myroom

  ```

  ```python Python theme={null}
  tables = await room.datasets.list_tables()

  print(tables)  # ["users", "orders", "products", ...]

  ```

  ```javascript NodeJs theme={null}
  const tables = await room.datasets.listTables();

  console.log(tables); // ["users", "orders", "products", ...]

  ```

  ```typescript TypeScript theme={null}
  const tables = await room.datasets.listTables();

  console.log(tables); // ["users", "orders", "products", ...]

  ```

  ```dart Dart theme={null}
  final tables = await room.datasets.listTables();

  print(tables); // ["users", "orders", "products", ...]

  ```

  ```dotnet C# theme={null}
  var tables = await room.Datasets.ListTables();

  Console.WriteLine(string.Join(", ", tables)); // ["users", "orders", "products", ...]

  ```
</CodeGroup>

### `create_table_with_schema(...)`

* **Description**: Creates a new table with an optional schema and initial data. You can specify how the table should be created through the `mode` parameter.
  * **modes**:
    * `"create"`: Creates the table; fails if it already exists.
    * `"overwrite"`: Drops the existing table (if any) and creates a new one.
    * `"create_if_not_exists"`: Creates the table only if it does not already exist.
* **Parameters**:
  * **name**: The name of the new table.
  * **schema**: An optional record defining column names and their data types.
  * **data**: An optional array of initial records to populate the table. Prefer batching records together rather than issuing many single-row writes.
  * **mode**: The creation mode (default is `"create"`).
* **Returns**: A promise that resolves once the table is created.

**Example**:

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset create \
    --room myroom \
    --table users \
    --columns "id int, username text, email text" \
    --data-json '[{"id":1,"username":"alice","email":"alice@example.com"},{"id":2,"username":"bob","email":"bob@example.com"}]'

  ```

  ```python Python theme={null}
  import pyarrow as pa

  await room.datasets.create_table_with_schema(
    name="users",
    schema={
      "id": pa.int64(),
      "username": pa.string(),
      "email": pa.string(),
    },
    data=[
      {"id": 1, "username": "alice", "email": "alice@example.com" },
      {"id": 2, "username": "bob", "email": "bob@example.com" }
    ],
    mode="create"
  )

  ```

  ```javascript NodeJs theme={null}
  import { Field, Int64, Schema, Utf8 } from "apache-arrow";

  await room.datasets.createTableWithSchema({
    name: "users",
    schema: new Schema([
      new Field("id", new Int64()),
      new Field("username", new Utf8()),
      new Field("email", new Utf8()),
    ]),
    mode: "create",
  });

  ```

  ```typescript TypeScript theme={null}
  import { Field, Int64, Schema, Utf8 } from "apache-arrow";

  await room.datasets.createTableWithSchema({
    name: "users",
    schema: new Schema([
      new Field("id", new Int64()),
      new Field("username", new Utf8()),
      new Field("email", new Utf8()),
    ]),
    mode: "create",
  });

  ```

  ```dart Dart theme={null}
  await room.datasets.createTableWithArrowSchema(
    name: "users",
    schema: arrowIpcSchema,
    mode: "create",
  );

  ```

  ```dotnet C# theme={null}
  await room.Datasets.CreateTableWithSchema(
    "users",
    new ArrowSchema(new[]
    {
      new ArrowField("id", Int64Type.Default, true),
      new ArrowField("username", StringType.Default, true),
      new ArrowField("email", StringType.Default, true),
    }, null),
    CreateMode.create
  );

  ```
</CodeGroup>

### `create_table_from_data(...)`

* **Description**: Creates a table using only data and an optional mode.
* **Parameters**:
  * **name**: The table name to create.
  * **data**: An array of records to initialize the table with.
  * **mode**: Table creation mode (default `"create"`).
* **Returns**: A promise that resolves once the table is created.

**Example**:

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset create \
    --room myroom \
    --table orders \
    --mode overwrite \
    --data-json '[{"id":1,"product":"Laptop","quantity":2},{"id":2,"product":"Phone","quantity":5}]'

  ```

  ```python Python theme={null}
  await room.datasets.create_table_from_data(
    name="orders",
    data=[
      {"id": 1, "product": "Laptop", "quantity": 2},
      {"id": 2, "product": "Phone", "quantity": 5},
    ],
    mode="overwrite"
  )

  ```

  ```javascript NodeJs theme={null}
  await room.datasets.createTableFromData({
    name: "orders",
    data: [
      { id: 1, product: "Laptop", quantity: 2 },
      { id: 2, product: "Phone", quantity: 5 },
    ],
    mode: "overwrite",
  });

  ```

  ```typescript TypeScript theme={null}
  await room.datasets.createTableFromData({
    name: "orders",
    data: [
      { id: 1, product: "Laptop", quantity: 2 },
      { id: 2, product: "Phone", quantity: 5 },
    ],
    mode: "overwrite",
  });

  ```

  ```dart Dart theme={null}
  await room.datasets.createTableFromData(
    name: "orders",
    data: [
      {"id": 1, "product": "Laptop", "quantity": 2},
      {"id": 2, "product": "Phone", "quantity": 5},
    ],
    mode: "overwrite",
  );

  ```

  ```dotnet C# theme={null}
  await room.Datasets.CreateTableFromData(
    "orders",
    new List<Dictionary<string, object?>>
    {
      new() { ["id"] = 1, ["product"] = "Laptop", ["quantity"] = 2 },
      new() { ["id"] = 2, ["product"] = "Phone", ["quantity"] = 5 },
    },
    CreateMode.overwrite
  );

  ```
</CodeGroup>

### `drop_table(name, ...)`

* **Description**: Drops (deletes) a table by name, optionally ignoring if it does not exist.
* **Parameters**:
  * **name**: The name of the table to drop.
  * **ignoreMissing**: If `true`, no error is thrown if the table does not exist.
* **Returns**: A promise that resolves once the table is dropped.

**Example**:

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset drop \
    --room myroom \
    --table temp_table \
    --ignore-missing

  ```

  ```python Python theme={null}
  await room.datasets.drop_table(
    name="temp_table",
    ignore_missing=True
  )

  ```

  ```javascript NodeJs theme={null}
  await room.datasets.dropTable({
    name: "temp_table",
    ignoreMissing: true,
  });

  ```

  ```typescript TypeScript theme={null}
  await room.datasets.dropTable({
    name: "temp_table",
    ignoreMissing: true,
  });

  ```

  ```dart Dart theme={null}
  await room.datasets.dropTable(
    name: "temp_table",
    ignoreMissing: true,
  );

  ```

  ```dotnet C# theme={null}
  await room.Datasets.DropTable("temp_table", ignoreMissing: true);

  ```
</CodeGroup>

### `add_columns(...)`

* **Description**: Adds one or more columns to an existing table, specifying default value expressions.
* **Parameters**:
  * **table**: Name of the target table.
  * **newColumns**: A record mapping column names to default value expressions (SQL or literal).
* **Returns**: A promise that resolves once the columns are added.

For Dart, the expression-based helper is `addColumnWithExpression(...)`. If you want to add columns by explicit Arrow schema instead, use `addColumnsWithSchema(...)`.

**Example**:

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset add-columns \
    --room myroom \
    --table users \
    --columns "isActive bool, createdAt timestamp"

  ```

  ```python Python theme={null}
  await room.datasets.add_columns(
    table="users",
    new_columns={
      "isActive": "true",
      "createdAt": "CURRENT_TIMESTAMP",
    }
  )

  ```

  ```javascript NodeJs theme={null}
  await room.datasets.addColumns({
    table: "users",
    newColumns: {
      isActive: "true",
      createdAt: "CURRENT_TIMESTAMP",
    },
  });

  ```

  ```typescript TypeScript theme={null}
  await room.datasets.addColumns({
    table: "users",
    newColumns: {
      isActive: "true",
      createdAt: "CURRENT_TIMESTAMP",
    },
  });

  ```

  ```dart Dart theme={null}
  await room.datasets.addColumnWithExpression(
    table: "users",
    newColumns: {
      "isActive": "true",
      "createdAt": "CURRENT_TIMESTAMP",
    },
  );

  ```

  ```dotnet C# theme={null}
  await room.Datasets.AddColumns(
    "users",
    new Dictionary<string, string>
    {
      ["isActive"] = "true",
      ["createdAt"] = "CURRENT_TIMESTAMP",
    }
  );

  ```
</CodeGroup>

### `drop_columns(...)`

* **Description**: Drops (removes) one or more columns from an existing table.
* **Parameters**:
  * **table**: Name of the target table.
  * **columns**: An array of column names to remove.
* **Returns**: A promise that resolves once the columns are dropped.

**Example**:

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset drop-columns \
    --room myroom \
    --table users \
    --column deprecatedColumn1 \
    --column deprecatedColumn2

  ```

  ```python Python theme={null}
  await room.datasets.drop_columns(
    table="users",
    columns=["deprecatedColumn1", "deprecatedColumn2"]
  )

  ```

  ```javascript NodeJs theme={null}
  await room.datasets.dropColumns({
    table: "users",
    columns: ["deprecatedColumn1", "deprecatedColumn2"],
  });

  ```

  ```typescript TypeScript theme={null}
  await room.datasets.dropColumns({
    table: "users",
    columns: ["deprecatedColumn1", "deprecatedColumn2"],
  });

  ```

  ```dart Dart theme={null}
  await room.datasets.dropColumns(
    table: "users",
    columns: ["deprecatedColumn1", "deprecatedColumn2"],
  );

  ```

  ```dotnet C# theme={null}
  await room.Datasets.DropColumns(
    "users",
    new List<string> { "deprecatedColumn1", "deprecatedColumn2" }
  );

  ```
</CodeGroup>

### `insert(table, records)`

* **Description**: Inserts one or more new records into a table.
* **Parameters**:
  * **table**: The name of the table to insert into.
  * **records**: An array of objects, each containing column-value pairs.
* **Returns**: A promise that resolves once the records are inserted.

**Example**:

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset insert \
    --room myroom \
    --table users \
    --json '[{"id":3,"username":"charlie","email":"charlie@example.com"},{"id":4,"username":"dana","email":"dana@example.com"}]'

  ```

  ```python Python theme={null}
  await room.datasets.insert(
    table="users",
    records=[
      { "id": 3, "username": "charlie", "email": "charlie@example.com" },
      { "id": 4, "username": "dana", "email": "dana@example.com" },
    ],
  )

  ```

  ```javascript NodeJs theme={null}
  await room.datasets.insert({
    table: "users",
    records: [
      { id: 3, username: "charlie", email: "charlie@example.com" },
      { id: 4, username: "dana", email: "dana@example.com" },
    ],
  });

  ```

  ```typescript TypeScript theme={null}
  await room.datasets.insert({
    table: "users",
    records: [
      { id: 3, username: "charlie", email: "charlie@example.com" },
      { id: 4, username: "dana", email: "dana@example.com" },
    ],
  });

  ```

  ```dart Dart theme={null}
  await room.datasets.insert(
    table: "users",
    records: [
      { "id": 3, "username": "charlie", "email": "charlie@example.com" },
      { "id": 4, "username": "dana", "email": "dana@example.com" },
    ],
  );

  ```

  ```dotnet C# theme={null}
  await room.Datasets.Insert(
    "users",
    new List<Dictionary<string, object?>>
    {
      new() { ["id"] = 3, ["username"] = "charlie", ["email"] = "charlie@example.com" },
      new() { ["id"] = 4, ["username"] = "dana", ["email"] = "dana@example.com" },
    }
  );

  ```
</CodeGroup>

### `update(table, where, ...)`

* **Description**: Updates existing records in a table.
* **Parameters**:
  * **table**: Name of the table to update.
  * **where**: A SQL `WHERE` clause specifying which records to update (e.g. `"id = 123"`).
  * **values**: A record of key-value pairs for direct assignment or expressions (e.g. `{ age: 30 }` or `{ age: new DatasetExpression("age + 1") }` in typed clients).
* **Returns**: A promise that resolves once the update is complete.

**Example**:

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset update \
    --room myroom \
    --table users \
    --where "id = 3" \
    --values-json '{"email":"newcharlie@example.com","loginCount":{"expression":"loginCount + 1"}}'

  ```

  ```python Python theme={null}
  await room.datasets.update(
    table="users",
    where="id = 3",
    values={
      "email": "newcharlie@example.com",
      "loginCount": DatasetExpression("loginCount + 1"),
    },
  )

  ```

  ```javascript NodeJs theme={null}
  await room.datasets.update({
    table: "users",
    where: "id = 3",
    values: {
      email: "newcharlie@example.com",
      loginCount: new DatasetExpression("loginCount + 1"),
    },
  });

  ```

  ```typescript TypeScript theme={null}
  await room.datasets.update({
    table: "users",
    where: "id = 3",
    values: {
      email: "newcharlie@example.com",
      loginCount: new DatasetExpression("loginCount + 1"),
    },
  });

  ```

  ```dart Dart theme={null}
  await room.datasets.update(
    table: "users",
    where: "id = 3",
    values: {
      "email": "newcharlie@example.com",
      "loginCount": DatasetExpression("loginCount + 1"),
    },
  );

  ```

  ```dotnet C# theme={null}
  await room.Datasets.Update(
    "users",
    "id = 3",
    values: new Dictionary<string, object?>
    {
      ["email"] = "newcharlie@example.com",
      ["loginCount"] = new DatasetExpression("loginCount + 1")
    }
  );

  ```
</CodeGroup>

### `delete(table, where)`

* **Description**: Deletes records from a table that match a specified condition.
* **Parameters**:
  * **table**: The target table.
  * **where**: A SQL `WHERE` clause for filtering which records to delete.
* **Returns**: A promise that resolves once the records are deleted.

**Example**:

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset delete \
    --room myroom \
    --table users \
    --where "id = 4"

  ```

  ```python Python theme={null}
  await room.datasets.delete(
    table="users",
    where="id = 4"
  )

  ```

  ```javascript NodeJs theme={null}
  await room.datasets.delete({
    table: "users",
    where: "id = 4",
  });

  ```

  ```typescript TypeScript theme={null}
  await room.datasets.delete({
    table: "users",
    where: "id = 4",
  });

  ```

  ```dart Dart theme={null}
  await room.datasets.delete(
    table: "users",
    where: "id = 4",
  );

  ```

  ```dotnet C# theme={null}
  await room.Datasets.Delete(
    "users",
    "id = 4"
  );

  ```
</CodeGroup>

### `merge(table, records, ...)`

* **Description**: Performs an **upsert** (update/insert) by merging incoming records into an existing table. Records matching the `on` column are updated; otherwise, new rows are inserted.
* **Parameters**:
  * **table**: The target table.
  * **on**: The column name used to match existing records.
  * **records**: The record(s) to merge/upsert.
* **Returns**: A promise that resolves once the operation is complete.

**Example**:

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset merge \
    --room myroom \
    --table users \
    --on id \
    --json '[{"id":1,"username":"alice","email":"alice_new@example.com"},{"id":5,"username":"eric","email":"eric@example.com"}]'

  ```

  ```python Python theme={null}
  await room.datasets.merge(
    table="users",
    on="id",
    records=[
      { "id": 1, "username": "alice", "email": "alice_new@example.com" },
      { "id": 5, "username": "eric", "email": "eric@example.com" },
    ],
  )

  ```

  ```javascript NodeJs theme={null}
  await room.datasets.merge({
    table: "users",
    on: "id",
    records: [
      { id: 1, username: "alice", email: "alice_new@example.com" },
      { id: 5, username: "eric", email: "eric@example.com" },
    ],
  });

  ```

  ```typescript TypeScript theme={null}
  await room.datasets.merge({
    table: "users",
    on: "id",
    records: [
      { id: 1, username: "alice", email: "alice_new@example.com" },
      { id: 5, username: "eric", email: "eric@example.com" },
    ],
  });

  ```

  ```dart Dart theme={null}
  await room.datasets.merge(
    table: "users",
    on: "id",
    records: [
      { "id": 1, "username": "alice", "email": "alice_new@example.com" },
      { "id": 5, "username": "eric", "email": "eric@example.com" },
    ],
  );

  ```

  ```dotnet C# theme={null}
  await room.Datasets.Merge(
    "users",
    "id",
    new List<Dictionary<string, object?>>
    {
      new() { ["id"] = 1, ["username"] = "alice", ["email"] = "alice_new@example.com" },
      new() { ["id"] = 5, ["username"] = "eric", ["email"] = "eric@example.com" },
    }
  );

  ```
</CodeGroup>

### `search(table, ...)`

* **Description**: Searches for records in a table. This can be used for plain text search, vector similarity search, or simple SQL filtering.
* **Parameters**:
  * **table**: The target table name.
  * **text**: An optional search string (if using full-text indexes).
  * **vector**: An optional numeric array for vector-based similarity queries.
  * **where**: SQL `WHERE` clause string or an object representing key-value equals conditions.
  * **offset**: Optional offset for pagination in Python and Dart.
  * **limit**: Maximum number of matching records to return.
  * **select**: An array of column names to be returned.
* **Returns**: Python returns a `pyarrow.Table`. JavaScript, TypeScript, Dart, and .NET return arrays/lists of matching records.

**Example**:

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset search \
    --room myroom \
    --table users \
    --where-json '{"username":"alice"}' \
    --limit 1

  ```

  ```python Python theme={null}
  results = await room.datasets.search(
    table="users",
    where={ "username": "alice" },
    limit=1
  )

  print(results.to_pylist())  # [{"id": 1, "username": "alice", "email": "alice@example.com"}]

  ```

  ```javascript NodeJs theme={null}
  const results = await room.datasets.search({
    table: "users",
    where: { username: "alice" },
    limit: 1,
  });

  console.log(results); // [{ id: 1, username: "alice", email: "alice@example.com" }]

  ```

  ```typescript TypeScript theme={null}
  const results = await room.datasets.search({
    table: "users",
    where: { username: "alice" },
    limit: 1,
  });

  console.log(results); // [{ id: 1, username: "alice", email: "alice@example.com" }]

  ```

  ```dart Dart theme={null}
  final results = await room.datasets.search(
    table: "users",
    where: {"username": "alice"},
    limit: 1,
  );

  print(results); // [{"id": 1, "username": "alice", "email": "alice@example.com"}]

  ```

  ```dotnet C# theme={null}
  var results = await room.Datasets.Search(
    "users",
    where: new Dictionary<string, object?> { ["username"] = "alice" },
    limit: 1
  );

  Console.WriteLine(results); // [{ "id": 1, "username": "alice", "email": "alice@example.com" }]

  ```
</CodeGroup>

### `optimize(table, ...)`

* **Description**: Optimizes a table (e.g., compacts its storage or rebuilds indexes if required).
* **Parameters**:
  * **table**: Name of the table to optimize.
  * **config**: Optional optimization configuration using Lance option names, including `compact_files`, `optimize_indices`, `cleanup_old_versions`, `target_rows_per_fragment`, `max_rows_per_group`, `max_bytes_per_file`, `materialize_deletions`, `materialize_deletions_threshold`, `defer_index_remap`, `num_threads`, `batch_size`, `compaction_mode`, `binary_copy_read_batch_bytes`, `num_indices_to_merge`, `index_names`, `retrain`, `older_than_seconds`, `retain_versions`, `delete_unverified`, `error_if_tagged_old_versions`, and `delete_rate_limit`.
* **Returns**: Optimization result details for compaction, index optimization, and cleanup.

**Example**:

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset optimize \
    --room myroom \
    --table users

  ```

  ```python Python theme={null}
  await room.datasets.optimize(table="users")

  ```

  ```javascript NodeJs theme={null}
  await room.datasets.optimize("users");

  ```

  ```typescript TypeScript theme={null}
  await room.datasets.optimize("users");

  ```

  ```dart Dart theme={null}
  await room.datasets.optimize(table: "users");

  ```

  ```dotnet C# theme={null}
  await room.Datasets.Optimize("users");

  ```
</CodeGroup>

### `stats(table, ...)`

* **Description**: Returns Lance dataset and data statistics for a table.
* **Parameters**:
  * **table**: Name of the table.
  * **max\_rows\_per\_group**: Optional row-group threshold used by Lance dataset stats.
* **Returns**: Parsed `dataset` and `data` statistics.

**Example**:

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset stats \
    --room myroom \
    --table users

  meshagent room dataset stats \
    --room myroom \
    --table users \
    --output json

  ```

  ```python Python theme={null}
  stats = await room.datasets.stats(table="users")

  ```

  ```typescript TypeScript theme={null}
  const stats = await room.datasets.stats({ table: "users" });

  ```

  ```dart Dart theme={null}
  final stats = await room.datasets.stats("users");

  ```
</CodeGroup>

### `create_index(...)`

* **Description**: Creates a Lance index on a dataset table.
* **Parameters**:
  * **table**: The target table name.
  * **config**: Index configuration. Uses Lance option names such as `column`, `index_type`, `name`, `replace`, `metric`, `num_partitions`, `num_sub_vectors`, `target_partition_size`, `filter_nan`, `train`, `fragment_ids`, `index_uuid`, `skip_transpose`, `num_bits`, `index_file_version`, `max_level`, `m`, `ef_construction`, `with_position`, `memory_limit`, `num_workers`, `skip_merge`, `base_tokenizer`, `language`, `max_token_length`, `lower_case`, `stem`, `remove_stop_words`, `custom_stop_words`, and `ascii_folding`.
* **Returns**: A promise that resolves once the index is created.

Supported `index_type` values include vector indexes (`IVF_PQ`, `IVF_HNSW_PQ`, `IVF_HNSW_SQ`, `IVF_RQ`) and scalar/text indexes (`BTREE`, `BITMAP`, `LABEL_LIST`, `NGRAM`, `ZONEMAP`, `INVERTED`, `FTS`, `BLOOMFILTER`, `RTREE`).

**Example**:

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset index-create \
    --room myroom \
    --table documents \
    --column embedding \
    --index-type IVF_PQ \
    --num-partitions 32 \
    --num-sub-vectors 8

  ```

  ```python Python theme={null}
  from meshagent.api import DatasetIndexConfig

  await room.datasets.create_index(
    table="documents",
    config=DatasetIndexConfig(
      column="embedding",
      index_type="IVF_PQ",
      num_partitions=32,
      num_sub_vectors=8,
    ),
  )

  ```

  ```javascript NodeJs theme={null}
  await room.datasets.createIndex({
    table: "documents",
    config: {
      column: "embedding",
      index_type: "IVF_PQ",
      num_partitions: 32,
      num_sub_vectors: 8,
    },
  });

  ```

  ```typescript TypeScript theme={null}
  await room.datasets.createIndex({
    table: "documents",
    config: {
      column: "embedding",
      index_type: "IVF_PQ",
      num_partitions: 32,
      num_sub_vectors: 8,
    },
  });

  ```

  ```dart Dart theme={null}
  await room.datasets.createIndex(
    table: "documents",
    config: const DatasetIndexConfig(
      column: "embedding",
      indexType: "IVF_PQ",
      numPartitions: 32,
      numSubVectors: 8,
    ),
  );

  ```

  ```dotnet C# theme={null}
  await room.Datasets.CreateIndex(
    "documents",
    new DatasetIndexConfig
    {
      Column = "embedding",
      IndexType = "IVF_PQ",
      NumPartitions = 32,
      NumSubVectors = 8,
    }
  );

  ```
</CodeGroup>

### `drop_index(...)`

* **Description**: Drop an index by name.
* **Parameters**:
  * **table**: Table name.
  * **name**: Index name to drop.
* **Returns**: `None`.
* **Availability**: Python, JavaScript/TypeScript, Dart, and .NET expose helpers today.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset index-drop \
    --room myroom \
    --table users \
    --name email_idx

  ```

  ```python Python theme={null}
  await room.datasets.drop_index(table="users", name="email_idx")

  ```

  ```typescript TypeScript theme={null}
  await room.datasets.dropIndex({
    table: "users",
    name: "email_idx",
  });

  ```

  ```dart Dart theme={null}
  await room.datasets.dropIndex(
    table: "users",
    name: "email_idx",
  );

  ```

  ```dotnet C# theme={null}
  await room.Datasets.DropIndex("users", "email_idx");

  ```
</CodeGroup>

### `list_indexes(table)`

* **Description**: Lists the indexes currently defined on a table.
* **Parameters**:
  * **table**: The name of the table for which to list indexes.
* **Returns**: A list of index entries. Entries include `name`, `columns`, `type`, `fields`, `type_url`, `num_rows_indexed`, `num_segments`, `total_size_bytes`, `details`, and `statistics`.

**Example**:

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset index \
    --room myroom \
    --table users

  ```

  ```python Python theme={null}
  indexes = await room.datasets.list_indexes(table="users")

  print(indexes)
  # Example output:
  # [TableIndex(name="email_idx", columns=["email"], type="scalar")]

  ```

  ```javascript NodeJs theme={null}
  const indexes = await room.datasets.listIndexes({ table: "users" });

  console.log(indexes);
  // Example output:
  // [{ name: "email_idx", columns: ["email"], type: "scalar" }]

  ```

  ```typescript TypeScript theme={null}
  const indexes = await room.datasets.listIndexes({ table: "users" });

  console.log(indexes); 
  // Example output:
  // [{ name: "email_idx", columns: ["email"], type: "scalar" }]

  ```

  ```dart Dart theme={null}
  final indexes = await room.datasets.listIndexes("users");

  print(indexes);
  // Example output:
  // [TableIndex(name: "email_idx", columns: ["email"], type: "scalar")]

  ```

  ```dotnet C# theme={null}
  var indexes = await room.Datasets.ListIndexes("users");

  Console.WriteLine(indexes);
  // Example output:
  // [{ "name": "email_idx", "columns": ["email"], "type": "scalar" }]

  ```
</CodeGroup>

### `list_versions(table)`

* **Description**: List historical versions of a table. Reads can target a specific `version` directly, and `restore` creates a new head version from an older snapshot.
* **Methods**:
  * `list_versions(table, branch=None)` → list of versions (`version`, `timestamp`, `metadata`) for the selected branch.
  * `search(table, branch=None, version=None)` → read a branch head or a specific historical version without any checkout step.
  * `restore(table, version, branch=None)` → restore a table branch to a prior version by creating a new head commit.
* **Availability**: Python exposes `list_versions`, `search(..., version=...)`, `restore`, and dataset branch operations. TypeScript exposes `listVersions`, `restore`, and branch helpers. .NET exposes `ListVersions` and `Restore`. Dart currently exposes `listVersions`.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset version \
    --room myroom \
    --table users

  ```

  ```python Python theme={null}
  versions = await room.datasets.list_versions(table="users")
  await room.datasets.restore(table="users", version=versions[-1].version)

  ```

  ```dart Dart theme={null}
  final versions = await room.datasets.listVersions("users");
  for (final version in versions) {
    print("${version.version} ${version.timestamp}");
  }

  ```
</CodeGroup>

### `list_branches()`

* **Description**: List, create, and delete dataset branches for a namespace. Table reads and writes can then target a branch directly with `branch=...`.
* **Methods**:
  * `list_branches()` → list available branches.
  * `create_branch(branch, from_branch=None)` → create a branch from the head of `main` or another branch.
  * `delete_branch(branch)` → delete a non-`main` branch.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room dataset branch list --room myroom
  meshagent room dataset branch create --room myroom --branch exp --from-branch main

  ```

  ```python Python theme={null}
  await room.datasets.create_branch(branch="exp")
  rows = await room.datasets.search(table="users", branch="exp")
  branches = await room.datasets.list_branches()

  ```

  ```typescript TypeScript theme={null}
  await room.datasets.createBranch({ branch: "exp" });
  const rows = await room.datasets.search({ table: "users", branch: "exp" });
  const branches = await room.datasets.listBranches();

  ```
</CodeGroup>

### Additional dataset operations

The current SDKs and CLI include a few operations that are useful once tables move beyond basic CRUD:

* `rename_table(...)` renames a table without copying its data.
* `sql(...)`, `open_sql_query(...)`, `execute_sql(...)`, `sql_stream(...)`, and `execute_sql_statement(...)` run SQL against room datasets.
* `watch_table(...)` streams table changes.
* `count(...)` returns the matching row count for a table query.
* `restore(...)` restores a table to a previous version.
* `meshagent room dataset import` imports local data into a room table.
* `meshagent room dataset sql` runs SQL from the CLI.

## Related guides

* [Room API Overview](./overview)
* [Memory API](./memory)
