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

# Term

> Look for exact token matches in the source document, without any further processing of the query string

Term queries look for exact token matches. A term query is like an exact string match, but at the
token level.

Unlike [match](/documentation/full-text/match) or [phrase](/documentation/full-text/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:

<CodeGroup>
  ```sql SQL theme={null}
  -- Term query 1
  SELECT description, rating, category
  FROM mock_items
  WHERE description === 'running';

  -- Term query 2
  SELECT description, rating, category
  FROM mock_items
  WHERE description === 'RUNNING';
  ```

  ```ts Drizzle theme={null}
  import { search } from "@paradedb/drizzle-paradedb";

  // Term query 1
  await db
    .select({
      description: mockItems.description,
      rating: mockItems.rating,
      category: mockItems.category,
    })
    .from(mockItems)
    .where(search.term(mockItems.description, "running"));

  // Term query 2
  await db
    .select({
      description: mockItems.description,
      rating: mockItems.rating,
      category: mockItems.category,
    })
    .from(mockItems)
    .where(search.term(mockItems.description, "RUNNING"));
  ```

  ```python Django theme={null}
  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')
  ```

  ```python SQLAlchemy theme={null}
  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(),
      }
  ```

  ```ruby Rails theme={null}
  # Term query 1
  MockItem.search(:description)
          .term("running")
          .select(:description, :rating, :category)

  # Term query 2
  MockItem.search(:description)
          .term("RUNNING")
          .select(:description, :rating, :category)
  ```

  ```cs EF Core theme={null}
  await dbContext
      .MockItems.Where(item => EF.Functions.Term(item.Description, "running"))
      .Select(item => new { item.Description, item.Rating, item.Category })
      .ToListAsync();

  await dbContext
      .MockItems.Where(item => EF.Functions.Term(item.Description, "RUNNING"))
      .Select(item => new { item.Description, item.Rating, item.Category })
      .ToListAsync();
  ```
</CodeGroup>

The first query returns:

```csv theme={null}
     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`.

<Note>
  All tokenizers besides the literal tokenizer
  [lowercase](/documentation/token-filters/lowercase) tokens by default. Make
  sure to account for this when searching for a term.
</Note>

<Note>
  If you are using `===` to do an exact string match on the original text, make
  sure that the text uses the
  [literal](/documentation/tokenizers/available-tokenizers/literal) tokenizer.
</Note>

## How It Works

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.

## Examples

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](/documentation/indexing/create-index) |
| Sleek run shoe      | `sleek` `run` `shoe`      | ❌     | Does not contain the token `running`. | [Stemming](/documentation/indexing/create-index)    |
| Sleke ruining shoez | `sleke` `ruining` `shoez` | ❌     | Does not contain the token `running`. | [Fuzzy](/documentation/full-text/fuzzy)             |
| White jogging shoes | `white` `jogging` `shoes` | ❌     | Does not contain the token `running`. |                                                     |

## Term Set

Passing a text array to the right-hand side of `===` means "find all documents containing any one of these tokens."

<CodeGroup>
  ```sql SQL theme={null}
  SELECT description, rating, category
  FROM mock_items
  WHERE description === ARRAY['shoes', 'running'];
  ```

  ```ts Drizzle theme={null}
  import { search } from "@paradedb/drizzle-paradedb";

  await db
    .select({
      description: mockItems.description,
      rating: mockItems.rating,
      category: mockItems.category,
    })
    .from(mockItems)
    .where(search.term(mockItems.description, ["shoes", "running"]));
  ```

  ```python Django theme={null}
  from paradedb import ParadeDB, TermSet

  MockItem.objects.filter(
      description=ParadeDB(TermSet('shoes', 'running'))
  ).values('description', 'rating', 'category')
  ```

  ```python SQLAlchemy theme={null}
  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()
  ```

  ```ruby Rails theme={null}
  MockItem.search(:description)
          .term_set("shoes", "running")
          .select(:description, :rating, :category)
  ```

  ```cs EF Core theme={null}
  await dbContext
      .MockItems.Where(item => EF.Functions.Term(item.Description, new[] { "shoes", "running" }))
      .Select(item => new { item.Description, item.Rating, item.Category })
      .ToListAsync();
  ```
</CodeGroup>
