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

# Semantic Search

> Querying the index with natural language and filters

## Basic Search

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const results = await toolIndex.search('reset a billing password');

for (const result of results) {
  console.log(`${result.metadata.toolName} (${result.score.toFixed(2)})`);
}
```

## Search Options

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const matches = await toolIndex.search('reset a billing password', {
  topK: 5,                    // Maximum results (default: 10)
  threshold: 0.45,            // Minimum similarity (default: 0.3)
  filter: (metadata) =>       // Metadata filter function
    metadata.owner === 'billing' &&
    !metadata.tags.includes('deprecated'),
  includeVector: false,       // Include raw vectors in results
});
```

### Options Reference

| Option          | Type       | Default | Description                    |
| --------------- | ---------- | ------- | ------------------------------ |
| `topK`          | `number`   | `10`    | Maximum results to return      |
| `threshold`     | `number`   | `0.3`   | Minimum similarity score (0-1) |
| `filter`        | `function` | -       | Filter function for metadata   |
| `includeVector` | `boolean`  | `false` | Include raw vectors in results |

## Search Results

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
interface SearchResult<T extends DocumentMetadata> {
  id: string;           // Document ID
  score: number;        // Similarity score (0-1)
  metadata: T;          // Document metadata
  vector?: number[];    // Embedding vector (if includeVector: true)
}
```

## Filtering Results

### Simple Filters

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// Filter by owner
const results = await toolIndex.search('user management', {
  filter: (m) => m.owner === 'users',
});

// Filter by tag
const results = await toolIndex.search('payment', {
  filter: (m) => m.tags.includes('billing'),
});

// Exclude deprecated
const results = await toolIndex.search('list items', {
  filter: (m) => !m.deprecated,
});
```

### Complex Filters

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const results = await toolIndex.search('sensitive operation', {
  filter: (metadata) => {
    // Must be owned by specific teams
    const allowedOwners = ['billing', 'users', 'orders'];
    if (!allowedOwners.includes(metadata.owner)) return false;

    // Must not be deprecated
    if (metadata.deprecated) return false;

    // Must not be destructive OR user has elevated permissions
    if (metadata.risk === 'destructive' && !userHasPermission) return false;

    return true;
  },
});
```

## Similarity Thresholds

Adjust thresholds based on your use case:

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// Strict matching - only highly relevant results
const strict = await toolIndex.search(query, { threshold: 0.7 });

// Moderate matching - good balance
const moderate = await toolIndex.search(query, { threshold: 0.5 });

// Loose matching - include tangentially related
const loose = await toolIndex.search(query, { threshold: 0.3 });
```

<Tip>
  Start with a lower threshold (0.3-0.4) and increase it if you're getting too many irrelevant results.
</Tip>

## Non-Semantic Filtering

For filtering without semantic search, use `filter()`:

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// Get all tools by owner (no semantic ranking)
const billingTools = toolIndex.filter(
  (metadata) => metadata.owner === 'billing'
);

// Get all deprecated tools
const deprecated = toolIndex.filter(
  (metadata) => metadata.deprecated === true
);
```

## Performance Tips

### 1. Use Appropriate topK

Request only as many results as you need:

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// Good - only fetch what you'll display
const results = await toolIndex.search(query, { topK: 5 });

// Wasteful - fetching more than needed
const results = await toolIndex.search(query, { topK: 1000 });
```

### 2. Use Filters to Reduce Search Space

Apply metadata filters to narrow results before similarity ranking:

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// Filter first, then rank - more efficient
const results = await toolIndex.search(query, {
  filter: (m) => m.owner === 'billing',
  topK: 10,
});
```

### 3. Enable HNSW for Large Datasets

For datasets > 10,000 documents, enable HNSW indexing:

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const db = new VectoriaDB({
  useHNSW: true,
  hnsw: { efSearch: 50 },
});
```

See [HNSW](/vectoriadb/guides/hnsw) for details.

## Error Handling

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
import { QueryValidationError } from 'vectoriadb';

try {
  const results = await toolIndex.search(query, { topK: -1 });
} catch (error) {
  if (error instanceof QueryValidationError) {
    console.error('Invalid search parameters:', error.message);
  }
}
```

## Related

<CardGroup cols={3}>
  <Card title="Indexing" icon="plus" href="/vectoriadb/guides/indexing">
    Adding documents
  </Card>

  <Card title="HNSW" icon="chart-network" href="/vectoriadb/guides/hnsw">
    Scaling search
  </Card>

  <Card title="Overview" icon="house" href="/vectoriadb/introduction">
    Getting started
  </Card>
</CardGroup>
