docs/documentation/full-text/term.mdx
Term queries look for exact token matches. A term query is like an exact string match, but at the token level.
Unlike match or phrase queries, term queries treat the query string as a finalized token. This means that the query string is taken as-is, without any further tokenization or filtering.
Term queries use the === operator. To understand exactly how it works, let's consider the following two term queries:
-- Term query 2 SELECT description, rating, category FROM mock_items WHERE description === 'RUNNING';
```python Django
from paradedb import ParadeDB, Term
# Term query 1
MockItem.objects.filter(
description=ParadeDB(Term('running'))
).values('description', 'rating', 'category')
# Term query 2
MockItem.objects.filter(
description=ParadeDB(Term('RUNNING'))
).values('description', 'rating', 'category')
from sqlalchemy import select
from sqlalchemy.orm import Session
from paradedb.sqlalchemy import search
term_query_1 = (
select(MockItem.description, MockItem.rating, MockItem.category)
.where(search.term(MockItem.description, "running"))
)
term_query_2 = (
select(MockItem.description, MockItem.rating, MockItem.category)
.where(search.term(MockItem.description, "RUNNING"))
)
with Session(engine) as session:
{
"rows_query_1": session.execute(term_query_1).all(),
"rows_query_2": session.execute(term_query_2).all(),
}
# Term query 1
MockItem.search(:description)
.term("running")
.select(:description, :rating, :category)
# Term query 2
MockItem.search(:description)
.term("RUNNING")
.select(:description, :rating, :category)
The first query returns:
description | rating | category
---------------------+--------+----------
Sleek running shoes | 5 | Footwear
(1 row)
However, the second query returns no results. This is because term queries look for exact matches, which includes
case sensitivity, and there are no documents in the example dataset containing the token RUNNING.
Under the hood, === simply finds all documents where any of their tokens are an exact string match against the query token.
A document's tokens are determined by the field's tokenizer and token filters, configured at index creation time.
Let’s consider a few more hypothetical documents to see whether they would be returned by the term query.
These examples assume that index uses the default tokenizer and token filters, and that the term query is
running.
| Original Text | Tokens | Match | Reason | Related |
|---|---|---|---|---|
| Sleek running shoes | sleek running shoes | ✅ | Contains the token running. | |
| Running shoes sleek | sleek running shoes | ✅ | Contains the token running. | |
| SLeeK RUNNING ShOeS | sleek running shoes | ✅ | Contains the token running. | Lowercasing |
| Sleek run shoe | sleek run shoe | ❌ | Does not contain the token running. | Stemming |
| Sleke ruining shoez | sleke ruining shoez | ❌ | Does not contain the token running. | Fuzzy |
| White jogging shoes | white jogging shoes | ❌ | Does not contain the token running. |
Passing a text array to the right-hand side of === means "find all documents containing any one of these tokens."
from paradedb import ParadeDB, TermSet
MockItem.objects.filter(
description=ParadeDB(TermSet('shoes', 'running'))
).values('description', 'rating', 'category')
from sqlalchemy import or_, select
from sqlalchemy.orm import Session
from paradedb.sqlalchemy import search
stmt = (
select(MockItem.description, MockItem.rating, MockItem.category)
.where(
or_(
search.term(MockItem.description, "shoes"),
search.term(MockItem.description, "running"),
)
)
)
with Session(engine) as session:
session.execute(stmt).all()
MockItem.search(:description)
.term_set("shoes", "running")
.select(:description, :rating, :category)