# Link your data to the Vector DB with Rell · Semantic search on Chromia using Vector DB · Learn Chromia

> This lesson shows you how to wire your movie data into the Vector DB extension with Rell. You will:

Source: https://chromia.com/learn/vector-db-movie-demo/code-deep-dive/rell-interface/

Semantic search on Chromia using Vector DBLesson 13 of 15

1. [01Searching movies semantically on Chromia](https://chromia.com/learn/vector-db-movie-demo/introduction/)

Module 1: Project setup

1. [02Overview](https://chromia.com/learn/vector-db-movie-demo/setup/)
2. [03Choose an embedding model](https://chromia.com/learn/vector-db-movie-demo/setup/embedding-model/)
3. [04Configure your Rell module](https://chromia.com/learn/vector-db-movie-demo/setup/configure.rell/)
4. [05Deploy your Rell module](https://chromia.com/learn/vector-db-movie-demo/setup/deploy-rell-module/)
5. [06Finalize your Python environment](https://chromia.com/learn/vector-db-movie-demo/setup/finalize-python-env/)

Module 2: Running the data pipeline

1. [07Overview](https://chromia.com/learn/vector-db-movie-demo/data-pipeline/)
2. [08Preprocess movie data](https://chromia.com/learn/vector-db-movie-demo/data-pipeline/preprocess/)
3. [09Generate sentence embeddings](https://chromia.com/learn/vector-db-movie-demo/data-pipeline/generate-embeddings/)
4. [10Store vectors on the blockchain](https://chromia.com/learn/vector-db-movie-demo/data-pipeline/upload-vectors/)

1. [11Search the vector database](https://chromia.com/learn/vector-db-movie-demo/search/)

Module 4: A deep dive into the code

1. [12Overview](https://chromia.com/learn/vector-db-movie-demo/code-deep-dive/)
2. [13Link your data to the Vector DB with Rell](https://chromia.com/learn/vector-db-movie-demo/code-deep-dive/rell-interface/)
3. [14Work with Chromia through the Python client](https://chromia.com/learn/vector-db-movie-demo/code-deep-dive/python-client/)

1. [15Use cases and extensions](https://chromia.com/learn/vector-db-movie-demo/use-cases/)

[Learn](https://chromia.com/learn/)[Semantic search on Chromia using Vector DB](https://chromia.com/learn/vector-db-movie-demo/)

13 / 15Module 4: A deep dive into the codeAdvanced

# Link your data to the Vector DB with Rell

This lesson shows you how to wire your movie data into the Vector DB extension with Rell. You will:

* Keep movie metadata next to its vectors
* Insert movies and their vectors in batches
* Retrieve detailed search results through Rell query templates

Each vector is tied to a movie's `rowid`. You can reuse this pattern for any other domain.

## Movie entity structure

The main entity stores the movie metadata you need:

rell

```
entity movie {
    wiki_id: integer;
    title: text;
    plot: text;
    release_date: text;
    box_office: text;
    runtime: text;
    languages: text;
    countries: text;
    genres: text;
}
```

You use these fields to filter search results and display them.

## Adding vectors alongside movies

Each vector points to a movie through the movie's `rowid`, which is its primary key. The following code adds movies and vectors together in a single operation.

### `movie_input` struct

The client must send movies in this format:

rell

```
struct movie_input {
    wiki_id: integer;
    title: text;
    plot: text;
    release_date: text;
    box_office: text;
    runtime: text;
    languages: text;
    countries: text;
    genres: text;
    vector: text;
}
```

### `add_movies`: batch insert movies and vectors

Rather than sending movies one at a time, call this operation once with a full list of movies and their vectors:

rell

```
val CONTEXT_MOVIE = 0; // vector context ID for movies

operation add_movies(movies: list<movie_input>) {
    val vector_ids = list<vector_db_data>();
    for (movie in movies) {
        val created = create movie(
            wiki_id = movie.wiki_id,
            title = movie.title,
            plot = movie.plot,
            release_date = movie.release_date,
            box_office = movie.box_office,
            runtime = movie.runtime,
            languages = movie.languages,
            countries = movie.countries,
            genres = movie.genres 
        );
        vector_ids.add(vector_db_data(movie.vector, created.rowid.to_integer()));
    }
    store_vectors(CONTEXT_MOVIE, vector_ids);
}
```

All vectors are written in one batch through `store_vectors`, which improves performance on large datasets.

## Vector context

`CONTEXT_MOVIE` sets the **context** for this group of vectors.  
A context ID marks a separate vector domain. For example, movies, legal documents, and support tickets could each have their own context.

Because of this, you can apply the **same embedding model** to several kinds of data and keep their results separate.

You choose the integer ID yourself. The demo assigns `0` to movies; in your own project, assign other IDs to other content types.

## Querying search results

After your data and vectors are stored on-chain, you can run semantic searches with Rell query templates. Results include similarity scores and can be narrowed with optional filters.

### `get_movies_with_distance`: include similarity score

rell

```
struct movie_with_distance {
    movie: struct<movie>;
    distance: decimal;
}

query get_movies_with_distance(closest_results: list<object_distance>): list<movie_with_distance> {
    val closest_result_ids = closest_results @ {} ( @set(rowid(.id)) );
    val movies_map = movie @ { .rowid in closest_result_ids } (
        @map(.rowid.to_integer(), .to_struct())
    );

    val results = list<movie_with_distance>();
    for (closest_result in closest_results) {
        results.add(movie_with_distance(
            movies_map[closest_result.id],
            closest_result.distance
        ));
    }

    return results;
}
```

For each match, this template returns the complete movie metadata together with its distance from the query vector.

### `get_movies_with_filter`: filter by genre

rell

```
query get_movies_with_filter(
    closest_results: list<object_distance>,
    genre_filter: text
): list<movie_with_distance> {
    val closest_result_ids = closest_results @ {} ( @set(rowid(.id)) );
    val movies_map = movie @ { .rowid in closest_result_ids } (
        @map(.rowid.to_integer(), .to_struct())
    );

    val results = list<movie_with_distance>();
    for (closest_result in closest_results) {
        val m = movies_map[closest_result.id];
        if (m.genres.contains(genre_filter)) {
            results.add(movie_with_distance(m, closest_result.distance));
        }
    }

    return results;
}
```

Here the results are restricted to one genre. You can change the filter to use other fields, such as release date, language, or runtime.

## Summary

* Movie metadata lives in an `entity`, and vectors reference it through `rowid`
* `add_movies` inserts movies and vectors in one operation
* `store_vectors` writes every vector in a single batch
* Rell query templates return detailed search results with distance scores and optional filters

With this foundation, you can run semantic vector search on-chain and extend it to your own domain and data.

Written for this site from Chromia’s public course. Code samples are the course’s own.

[← Previous**Module 4: A deep dive into the code**](https://chromia.com/learn/vector-db-movie-demo/code-deep-dive/)[Next →**Work with Chromia through the Python client**](https://chromia.com/learn/vector-db-movie-demo/code-deep-dive/python-client/)

On this page

* [Movie entity structure](#movie-entity-structure)
* [Adding vectors alongside movies](#adding-vectors-alongside-movies)
* [Vector context](#vector-context)
* [Querying search results](#querying-search-results)
* [Summary](#summary)
