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

# Keyword search

TopK supports keyword search with the BM25 ranking function.

To perform a keyword search on your documents, use the [`match()`](/sdk/topk-py/query#match) function.

## Define a collection schema for keyword search

Define a schema with a [`text()`](/sdk/topk-py/schema#text) field and add a [`keyword_index()`](/sdk/topk-py/schema#keyword_index):

<CodeGroup>
  ```python Python theme={null}
  from topk_sdk.schema import text, keyword_index

  client.collections().create(
      "books",
      schema={
          "title": text().index(keyword_index()),
          "description": text().index(keyword_index()),
      },
  )
  ```

  ```js Javascript theme={null}
  import { text, keywordIndex } from "topk-js/schema";

  await client.collections().create("books", {
    title: text().index(keywordIndex()),
    description: text().index(keywordIndex()),
  });
  ```
</CodeGroup>

## Run a keyword search

To run a keyword search on the `title` and `description` fields using the [`match()`](/sdk/topk-py/query#match) function.
We'll query the collection to match the term `"great"` in the `title` field or the term `"novel"` in any of the keyword-indexed text fields:

<CodeGroup>
  ```python Python theme={null}
  from topk_sdk.query import select, fn, match, field

  docs = client.collection("books").query(
      select(
          "title",
          "description",
          # Score documents using BM25 algorithm
          text_score=fn.bm25_score(),
      )
      # Filter documents that have the `great` keyword in the `title` field
      # or the `novel` in any of the text-indexed fields.
      .filter(
          match("great", field="title") | match("novel")
      )
      # Return top 10 documents with the highest text score
      .topk(field("text_score"), 10)
  )

  # Example result:

  [
    {
      _id: '1',
      title: 'The Great Gatsby',
      description: 'A novel about a great man who wants to be rich and famous',
      text_score: 0.864456057548523
    },
    {
      _id: '2',
      title: 'The Catcher in the Rye',
      description: 'A novel about a boy who wants to be a writer',
      text_score: 0.1948474943637848,
    }
  ]
  ```

  ```js Javascript theme={null}
  import { select, field, fn, match } from "topk-js/query";

  const docs = await client.collection(name).query(
    select({
      title: field("title"),
      description: field("description"),
      // Score documents using BM25 algorithm
      text_score: fn.bm25Score(),
    })
    // Filter documents that have the `great` keyword in the `title` field
    // or the `novel` in any of the text-indexed fields.
    .filter(match("great", { field: "title" }).or(match("novel")))
    // Return top 10 documents with the highest text score
    .topk(field("text_score"), 10)
  );

  // Example result:

  [
    {
      _id: '1',
      title: 'The Great Gatsby',
      description: 'A novel about a great man who wants to be rich and famous',
      text_score: 0.864456057548523
    },
    {
      _id: '2',
      title: 'The Catcher in the Rye',
      description: 'A novel about a boy who wants to be a writer'
      text_score: 0.1948474943637848,
    }
  ]
  ```
</CodeGroup>

<Note>
  The `match()` function will by default execute against all
  fields with a [**keyword index**](/collections/create#keyword-index).
</Note>

TopK provides a powerful keyword search API allowing you to customize your search queries.
Read more about keyword search [here](/documents/query#keyword-search).
