---
title: "Search by meaning when the collection is · Agent Wranglers"
url: https://agentwranglers.se/playbook/search/engines-and-indexes/small-semantic-search
id: SRH-3
level: Optional
updated: 2026-10-27
build: a2a6bdfed830
tokens: 833
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Search by meaning when the collection is small

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Engines and indexes](https://agentwranglers.se/playbook/search/engines-and-indexes.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: SRH-3
- Level: Optional
- Chapter: [Engines and indexes](https://agentwranglers.se/playbook/search/engines-and-indexes.md)
- Rule: When a site has 5,000 items or fewer, rank search results by meaning as well as by words.
- Check: A set of 10 paraphrased questions, none sharing a title word with its answer, returns the right item in the top three for each.
- How: Embed each item's title, summary and aliases at build time, and store the vectors with the site. Embed the query, rank by similarity, and merge with word matches, as [Search by meaning and by words](https://agentwranglers.se/playbook/search/engines-and-indexes/hybrid-search.md) says. A few thousand vectors fit in memory, so no vector database is needed. Record the embedding model with the vectors, as [Record the embedding model with every vector](https://agentwranglers.se/playbook/search/engines-and-indexes/embedding-model-version.md) says. Measure it as [Measure retrieval on its own](https://agentwranglers.se/playbook/search/relevance/search-quality-tests.md) says.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
const cosine = (a, b) => a.reduce((sum, x, i) => sum + x * b[i], 0);
export const byMeaning = (queryVector, items) => items.map(item => ({ item, score: cosine(queryVector, item.vector) })).sort((a, b) => b.score - a.score);
```

### Python example

```python
import numpy as np

def by_meaning(query_vector: np.ndarray, vectors: np.ndarray, items: list[dict]) -> list[tuple[dict, float]]:
    scores = vectors @ query_vector
    return [(items[i], float(scores[i])) for i in np.argsort(-scores)]
```

## Related rules

- SRH-2 [Search by meaning and by words](https://agentwranglers.se/playbook/search/engines-and-indexes/hybrid-search.md) in Search
- SRH-4 [Record the embedding model with every vector](https://agentwranglers.se/playbook/search/engines-and-indexes/embedding-model-version.md) in Search
- SRH-17 [Test search results with a fixed query set](https://agentwranglers.se/playbook/search/relevance/search-quality-tests.md) in Search

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/search/engines-and-indexes/small-semantic-search">Agent Wranglers search playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Search by meaning and by words](https://agentwranglers.se/playbook/search/engines-and-indexes/hybrid-search.md)
- Next: [Record the embedding model with every vector](https://agentwranglers.se/playbook/search/engines-and-indexes/embedding-model-version.md)
- [Engines and indexes](https://agentwranglers.se/playbook/search/engines-and-indexes.md)
