fix(indexer): match elided titles when the release separates the apostrophe (#2762) - #2763
Conversation
…trophe (vavallee#2762) FoldForTitleMatch deletes both apostrophe forms so a possessive collapses to one token ("Ender's" -> "enders"), which is deliberate and pinned by its own tests. A release name keeps the character as a separator instead ("Stephen.King.L.Outsider.2018.FRENCH"), so a title that elides with an apostrophe ("L'Outsider", "l'isola") folded to a token no release name contains. The search answered zero results for a release the indexer had returned, and reported nothing. Try a second reading of the same alphabet, only after the strict one fails, at every point that judges a release: the indexer response gate (newznab.titleHasRelevantResult), the interactive and auto-grab filter (filterRelevantDebug), and the searcher's own relevance filter (filterRelevant). The strict reading is always attempted first, the second pass is skipped when the two readings are identical, and it returns nothing for a title with no apostrophe. No fold changes and no stored key changes, so there is no Rev bump and no backfill. Signed-off-by: Kassabji, Christophe <4427381+misterk72@users.noreply.github.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…ilter
Codecov reported one uncovered line in the previous commit: the subtitle
branch of filterRelevantDebug, where primaryTitle ("Dune: Messiah" -> "Dune")
makes the searcher consider the title's primary half as well. A release
routinely names the book without its subtitle, so that half needs the same
elision reading.
Reverting the four changed files to their pre-fix state fails this test,
together with the four elision cases and the test asserting the two filter
paths agree. The first attempt at the red proof was inconclusive because
removing the fallback from that single line left the variable unused and the
package failed to build rather than failing a test.
Signed-off-by: Kassabji, Christophe <4427381+misterk72@users.noreply.github.com>
vavallee
left a comment
There was a problem hiding this comment.
Nice work, and thanks for measuring it. Strict match first with the elided reading only as a fallback keeps possessives exactly as they were. I did look at the identity gate: the elided reading can shrink it to one word (Sac d'os gives [sac]), but tryMatch still needs the author tokens, so any widening stays within one author. Tests fail on main for the stated reason, and it merges and passes on current main.
|
Thanks for the review, and for checking the identity gate — that was the part I was least sure about. I verified your reading: in The branch is 11 commits behind Happy to add a test covering the case you raised, where the elided reading reduces the primary title to one token ( For what it is worth, the patch is running locally on a French library where the affected titles returned nothing at all before; those now match. |
|
Heads up, nothing for you to do yet. I found today that the relevance filter's two copies had drifted: #2502's guards only ever reached |
Summary
Fixes #2762.
FoldForTitleMatchdeletes both apostrophe forms so a possessive collapses to one token(
Ender's->enders), which is deliberate and pinned by two tests. A release name keeps thecharacter as a separator (
Stephen.King.L.Outsider.2018.FRENCH), so a title that elides with anapostrophe (
L'Outsider,l'isola) folded to a token no release name contains: the searchreturned zero results for a release the indexer had answered with, and reported nothing.
The fix adds a second reading of the same alphabet, tried only after the strict one fails, at
every point that judges a release:
newznab.titleHasRelevantResult-- the indexer response gate, which drops the whole responsebefore the cascade advances;
filterRelevantDebug-- the interactive search, and auto-grab, sinceSearchBookWithOutcomesprojects it;
filterRelevant-- the searcher own relevance filter, the only one that also applies theidentity gate.
Nothing that matches today changes behaviour: the strict reading is attempted first, the second
pass is skipped when the two readings are identical, and it returns nothing for a title with no
apostrophe. No fold changes and no stored key changes, so there is no
Revbump, no backfill andno new row in the shared fixture corpus.
docs/search-design.mdgains a section stating thedivergence and why the strict fold stays primary.
Checklist
git commit -s-- see Sign your workdocs/DEPLOYMENT.mdupdated if env vars, config, or upgrade path changed -- not applicable: no env var, config or upgrade path changedchangelog.d/(not an edit toCHANGELOG.md) -- see changelog.d/README.mdTest plan
go test ./cmd/... ./internal/...-- 57 packages, exit 0, run with Go 1.26.6, the version CI usesgofmt -l .andgo vet ./...-- clean across the repositorygolangci-lint runv2.11.4 on the changed packages -- 0 issuesinternal/indexer94.2%,internal/indexer/newznab87.1%,internal/textutil86.0%cd web && npm run build-- not run: no file underweb/is touched by this changeL'Outsider0 -> 2 releases, the typographic apostrophe 0 -> 2, the space spelling 2 -> 2, possessive matching unchangedEach added test fails without its part of the change: one per gate, plus one asserting the two
filter paths agree, which is the test kind the project already carries from #713.