examples · fts · 1 / 6
1. Index a document (write postings)
← FTS exampleswhat this does
Tokenises text and writes the resulting postings into the inverted index for the description field on shop.products. The doc_id you supply is the handle the search side returns - so it should be whatever you use to look the row up later (almost always the row's primary key).
when to use it
- You have a text column (description, body, comment) and you want to be able to search inside it.
- You're rebuilding an index after a backfill or a schema change.
- You want to update what's indexed for one row - re-POST the same
doc_idand the previous text is replaced atomically.
the request
FTS is a runtime endpoint - there is no [[extractions.fts]] block on the schema and no setup step. The first POST creates the index.
POST /v1/tenants/:t/fts/:schema/:field
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/fts/shop.products/description" \
-H "Authorization: Bearer $OC_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"doc_id": "p001",
"text": "Wireless over-ear headphones with active noise cancellation and 30-hour battery life."
}'db.fts.index(
"shop.products",
"description",
doc_id="p001",
text="Wireless over-ear headphones with active noise cancellation and 30-hour battery life.",
)await db.ftsIndex("shop.products", "description", {
doc_id: "p001",
text: "Wireless over-ear headphones with active noise cancellation and 30-hour battery life.",
});_, err := db.FTSIndex(ctx, "shop.products", "description", originchain.FTSIndexRequest{
DocID: "p001",
Text: "Wireless over-ear headphones with active noise cancellation and 30-hour battery life.",
}) what you get back
{
"ok": true,
"doc_id": "p001",
"field": "description",
"tokens_indexed": 12
} how it works
- The text is tokenised, lowercased, and the per-token postings are written to the inverted index keyed by
(schema, field, token). - If a doc with this
doc_idalready exists in this field's index, the previous postings are removed and the new ones written in a single atomic batch. There is no window where both versions are visible. - Each field is an independent index. Indexing
descriptiondoes nothing totitle.
common mistakes
- Forgetting to re-index on writes. Updating the source row's text in
/rowsdoes not update the FTS index. You have to POST to the FTS endpoint again, or wire a hook that does it for you. - Using something other than the primary key for
doc_id. Search returnsdoc_ids - if it's not the row's PK you'll need an extra lookup on every hit. - Indexing multi-MB blobs as a single doc. Very large documents bloat the postings and hurt scoring. Split into chunks (e.g. one doc_id per paragraph or per page) and let the search side merge.