Skip to content

fix(search-index): index every page in full - #420

Merged
ysyneu merged 2 commits into
feat/ai-srefrom
fix/meili-full-pages
Sep 22, 2026
Merged

ysyneu merged 2 commits into
feat/ai-srefrom
fix/meili-full-pages

Conversation

@ysyneu

@ysyneu ysyneu commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Why

scripts/upload.sh cut each page's cleaned text at 6000 characters before indexing it. The CI runner is Ubuntu, where GNU cut -c counts bytes, so a Chinese page kept about 2000 characters:

  • zh: 129 of 279 pages were cut, 44.3% of the text never reached the index
  • en: 144 of 281 pages were cut, 47.2% lost
  • the longest pages (changelog, CLI reference, API catalog) kept 8–12%

Keyword search could not match anything past the cut, and answers that live in the second half of a long page were unreachable.

What changes

  • Each Meilisearch document holds the whole cleaned page. Document ids are unchanged (md5 of the path), so the next sync upserts in place.
  • The content goes to jq through stdin. As a --arg, a page over 128 KiB would exceed Linux's limit on a single command-line argument.

Required before this reaches main

The index's embedder must bound its own input:

"documentTemplate": "A document named {{doc.title}} with content {{doc.content | truncate: 6000}}"

Meilisearch 1.39 sends the full rendered template to a REST embedder regardless of documentTemplateMaxBytes, and text-embedding-v4 rejects input over its length limit (Range of input length should be [1, 16000]). One long page fails the whole indexing batch (indexedDocuments: 0). With the truncate filter the batch indexes cleanly: a test index built by this branch's script holds 562 documents with 562 embeddings, the largest page at ~72 KB.

Rollback

Revert this commit and run the workflow once with workflow_dispatch; the ids are the same, so the old truncated documents overwrite the full ones in place.

upload.sh cut each page's cleaned text at 6000 characters (bytes on the
ubuntu runner), so keyword search never saw the rest of a long page: 129 of
279 zh pages and 144 of 281 en pages were cut, losing 44% and 47% of their
text. Each Meilisearch document now holds the whole cleaned page; ids are
unchanged, so the next sync upserts in place.

The content reaches jq through stdin: as a --arg, a page over 128 KiB would
exceed Linux's limit on a single command-line argument.

The index embedder must bound its own input, e.g. a documentTemplate of
"A document named {{doc.title}} with content {{doc.content | truncate: 6000}}":
Meilisearch 1.39 sends the full rendered template to a REST embedder
regardless of documentTemplateMaxBytes, and text-embedding-v4 rejects a long
page, which fails the whole indexing batch.
The comment claimed the embedder reads only the first
documentTemplateMaxBytes of a document. Meilisearch does not apply that
setting to REST embedders; the cut happens in the index's documentTemplate
with the truncate filter.
@ysyneu
ysyneu deployed to development September 21, 2026 16:03 — with GitHub Actions Active
@ysyneu
ysyneu merged commit 2d57581 into feat/ai-sre Sep 22, 2026
2 checks passed
@ysyneu
ysyneu deleted the fix/meili-full-pages branch September 22, 2026 10:37

This branch was successfully deployed

1 active deployment
development 4b7f925f Deployed Sep 21, 2026 by ysyneu via upload #327
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant