---
title: Quickstart
description: Get started with ParadeDB in five minutes
canonical: https://docs.paradedb.com/documentation/getting-started/quickstart
---

This guide will walk you through a few queries to give you a feel for ParadeDB.

## Create Example Table

ParadeDB comes with a helpful procedure that creates a table populated with mock data to help
you get started. Run the following command to create this table.

```sql
CALL paradedb.create_bm25_test_table(
  schema_name => 'public',
  table_name => 'mock_items'
);
```

Then inspect the first 3 rows:

```sql
SELECT description, rating, category
FROM mock_items
LIMIT 3;
```

```ini Expected Response
       description        | rating |  category
--------------------------+--------+-------------
 Ergonomic metal keyboard |      4 | Electronics
 Plastic Keyboard         |      4 | Electronics
 Sleek running shoes      |      5 | Footwear
(3 rows)
```

Next, let's create a BM25 index called `search_idx` on this table. A BM25 index is a covering index, which means that multiple columns can be included in the same index.

```sql
CREATE INDEX search_idx ON mock_items
USING bm25 (id, description, category, rating, in_stock, created_at, metadata, weight_range)
WITH (key_field='id');
```

<Note>
  As a general rule of thumb, any columns that you want to filter, `GROUP BY`,
  `ORDER BY`, or aggregate as part of a full text query should be added to the
  index for faster performance.
</Note>

<Note>
  Note the mandatory `key_field` option. See [choosing a key
  field](/documentation/indexing/create-index#choosing-a-key-field) for more details.
</Note>

## Match Query

We're now ready to execute a basic text search query. We'll look for matches where `description` matches `running shoes` where `rating` is greater than `2`.

<CodeGroup>
```sql SQL
SELECT description, rating, category
FROM mock_items
WHERE description ||| 'running shoes' AND rating > 2
ORDER BY rating
LIMIT 5;
```

```python Django
from paradedb import Match, ParadeDB

MockItem.objects.filter(
    description=ParadeDB(Match('running shoes', operator='OR')),
    rating__gt=2
).values('description', 'rating', 'category').order_by('rating')[:5]
```

```ruby Rails
MockItem.search(:description)
        .matching_any("running shoes")
        .where(rating: 3..)
        .select(:description, :rating, :category)
        .order(:rating)
        .limit(5)
```

</CodeGroup>

```ini Expected Response
     description     | rating | category
---------------------+--------+----------
 White jogging shoes |      3 | Footwear
 Generic shoes       |      4 | Footwear
 Sleek running shoes |      5 | Footwear
(3 rows)
```

`|||` is ParadeDB's custom [match disjunction](/documentation/full-text/match#disjunction) operator, which means "find me all documents containing
`running OR shoes`.

If we want all documents containing `running AND shoes`, we can use ParadeDB's `&&&` [match conjunction](/documentation/full-text/match#conjunction) operator.

<CodeGroup>
```sql SQL
SELECT description, rating, category
FROM mock_items
WHERE description &&& 'running shoes' AND rating > 2
ORDER BY rating
LIMIT 5;
```

```python Django
from paradedb import Match, ParadeDB

MockItem.objects.filter(
    description=ParadeDB(Match('running shoes', operator='AND')),
    rating__gt=2
).values('description', 'rating', 'category').order_by('rating')[:5]
```

```ruby Rails
MockItem.search(:description)
        .matching_all("running shoes")
        .where(rating: 3..)
        .select(:description, :rating, :category)
        .order(:rating)
        .limit(5)
```
</CodeGroup>

```ini Expected Response
     description     | rating | category
---------------------+--------+----------
 Sleek running shoes |      5 | Footwear
(1 row)
```

## BM25 Scoring

Next, let's add [BM25 scoring](/documentation/sorting/score) to the results, which sorts matches by relevance. To do this, we'll use `pdb.score`.

<CodeGroup>
```sql SQL
SELECT description, pdb.score(id)
FROM mock_items
WHERE description ||| 'running shoes' AND rating > 2
ORDER BY score DESC
LIMIT 5;
```

```python Django
from paradedb import Match, ParadeDB, Score

MockItem.objects.filter(
    description=ParadeDB(Match('running shoes', operator='OR')),
    rating__gt=2
).annotate(
    score=Score()
).values('description', 'score').order_by('-score')[:5]
```

```ruby Rails
MockItem.search(:description)
        .matching_any("running shoes")
        .where(rating: 3..)
        .with_score
        .select(:description)
        .order(search_score: :desc)
        .limit(5)
```

</CodeGroup>

```ini Expected Response
     description     |   score
---------------------+-----------
 Sleek running shoes |  6.817111
 Generic shoes       | 3.8772602
 White jogging shoes | 3.4849067
(3 rows)
```

## Highlighting

Finally, let's also [highlight](/documentation/full-text/highlight) the relevant portions of the documents that were matched.
To do this, we'll use `pdb.snippet`.

<CodeGroup>
```sql SQL
SELECT description, pdb.snippet(description), pdb.score(id)
FROM mock_items
WHERE description ||| 'running shoes' AND rating > 2
ORDER BY score DESC
LIMIT 5;
```

```python Django
from paradedb import Match, ParadeDB, Score, Snippet

MockItem.objects.filter(
    description=ParadeDB(Match('running shoes', operator='OR')),
    rating__gt=2
).annotate(
    snippet=Snippet('description'),
    score=Score()
).values('description', 'snippet', 'score').order_by('-score')[:5]
```

```ruby Rails
MockItem.search(:description)
        .matching_any("running shoes")
        .where(rating: 3..)
        .with_snippet(:description)
        .with_score
        .select(:description)
        .order(search_score: :desc)
        .limit(5)
```

</CodeGroup>

```ini Expected Response
     description     |              snippet              |   score
---------------------+-----------------------------------+-----------
 Sleek running shoes | Sleek <b>running</b> <b>shoes</b> |  6.817111
 Generic shoes       | Generic <b>shoes</b>              | 3.8772602
 White jogging shoes | White jogging <b>shoes</b>        | 3.4849067
(3 rows)
```

## Top K

ParadeDB is highly optimized for quickly returning the [Top K](/documentation/sorting/topk) results out of the index. In SQL, this means queries that contain an `ORDER BY...LIMIT`:

<CodeGroup>
```sql SQL
SELECT description, rating, category
FROM mock_items
WHERE description ||| 'running shoes'
ORDER BY rating
LIMIT 5;
```

```python Django
from paradedb import Match, ParadeDB

MockItem.objects.filter(
    description=ParadeDB(Match('running shoes', operator='OR'))
).values('description', 'rating', 'category').order_by('rating')[:5]
```

```ruby Rails
MockItem.search(:description)
        .matching_any("running shoes")
        .select(:description, :rating, :category)
        .order(:rating)
        .limit(5)
```

</CodeGroup>

```ini Expected Response
     description     | rating | category
---------------------+--------+----------
 White jogging shoes |      3 | Footwear
 Generic shoes       |      4 | Footwear
 Sleek running shoes |      5 | Footwear
(3 rows)
```

## Facets

[Faceted queries](/documentation/aggregates/facets) allow a single query to return both the Top K results and an aggregate value,
which is more CPU-efficient than issuing two separate queries.

For example, the following query returns the top 3 results as well as the total number of results matched.

<CodeGroup>
```sql SQL
SELECT
     description, rating, category,
     pdb.agg('{"value_count": {"field": "id"}}') OVER ()
FROM mock_items
WHERE description ||| 'running shoes'
ORDER BY rating
LIMIT 5;
```

```python Django
from paradedb import Match, ParadeDB

rows, facets = (
    MockItem.objects
    .filter(description=ParadeDB(Match('running shoes', operator='OR')))
    .order_by('rating')
    .values('description', 'rating', 'category')[:5]
    .facets(agg='{"value_count": {"field": "id"}}')
)
```

```ruby Rails
relation = MockItem.search(:description)
                   .matching_any("running shoes")
                   .with_agg(agg: ParadeDB::Aggregations.value_count(:id))
                   .order(:rating)
                   .select(:description, :rating, :category)
                   .limit(5)

rows = relation.to_a
facets = relation.aggregates
```

</CodeGroup>

```ini Expected Response
     description     | rating | category |      agg
---------------------+--------+----------+----------------
 White jogging shoes |      3 | Footwear | {"value": 3.0}
 Generic shoes       |      4 | Footwear | {"value": 3.0}
 Sleek running shoes |      5 | Footwear | {"value": 3.0}
(3 rows)
```

That's it! Next, let's [load your data](/documentation/getting-started/load) to start running real queries.
