Search hints come back in a different order #49

Closed
opened 2026-08-03 22:22:09 +02:00 by Claude · 1 comment
Collaborator

Search hints come back in a different order.

/Search/Hints?searchTerm=alien over a production library — both servers find
the same seven items and neither misses one, but the order differs:

upstream ours
Movie · Alien Episode · Aliens of London (1)
Episode · Aliens of London (1) Episode · M. Night Shaym-Aliens!
Movie · Alien: Covenant Episode · What to Expect… An Alien Parasite
Series · Alien: Earth Movie · Alien
Movie · Alien: Romulus Movie · Alien: Covenant
Episode · What to Expect… An Alien Parasite Series · Alien: Earth
Episode · M. Night Shaym-Aliens! Movie · Alien: Romulus

Upstream leads with the exact match and ranks by how well the term matches.
Ours appears to group by type and sort within it, so the film called Alien
comes fourth behind three episodes that merely contain the word.

Array order is contract, and this is the one route where the order is the
answer: a search box shows the first few.

The reference library is too small for a term to match seven things, so no
scenario has ever ordered more than one hit.

Search hints come back in a different order. `/Search/Hints?searchTerm=alien` over a production library — both servers find the same seven items and neither misses one, but the order differs: | upstream | ours | |---|---| | Movie · Alien | Episode · Aliens of London (1) | | Episode · Aliens of London (1) | Episode · M. Night Shaym-Aliens! | | Movie · Alien: Covenant | Episode · What to Expect… An Alien Parasite | | Series · Alien: Earth | Movie · Alien | | Movie · Alien: Romulus | Movie · Alien: Covenant | | Episode · What to Expect… An Alien Parasite | Series · Alien: Earth | | Episode · M. Night Shaym-Aliens! | Movie · Alien: Romulus | Upstream leads with the exact match and ranks by how well the term matches. Ours appears to group by type and sort within it, so the film called `Alien` comes fourth behind three episodes that merely contain the word. Array order is contract, and this is the one route where the order *is* the answer: a search box shows the first few. The reference library is too small for a term to match seven things, so no scenario has ever ordered more than one hit.
Author
Collaborator

/Search/Hints is two queries, and this port was doing neither.

SqlSearchProvider scores every row whose folded CleanName holds the term,
first arm winning:

score condition
100 the whole name
80 the front of it
75 a word inside it (term + " ")
50 anywhere at all

80 beats 75, so Skyfall outranks Above Sky Line; and a name ending in the
term scores 50, not 75 — no trailing space — which is why upstream puts
The Matrix last for matrix. It cuts with score DESC, id ASC at
limit ?? 100, then SearchManager re-reads those ids ordered by SortName
and stably re-sorts by score. Net: score DESC, SortName ASC, and the cut
happens before paging, so TotalRecordCount is the capped count.

term upstream and now ours before
alien Alien, Aliens of London (1), Alien: Covenant, Alien: Earth, Alien: Romulus, … three episodes first, the film fourth
matrix Reloaded, Resurrections, Revolutions, The Matrix The Matrix first
love&limit=8 total 8 total 179
star&limit=12 total 12 total 145

128 of 128 request variants are now byte-identical to upstream — 28 terms
across bare, limited, paged, and type-filtered forms. Before, nearly all
differed. Also fixed here: Year, Folder and CollectionFolder are excluded
as upstream excludes them, a whitespace-only term is a 400 rather than the whole
library, and a term that folds to nothing matches nothing.

One existing test asserted total=2 for limit=1. That was this port's own
answer, not upstream's — verified live, alien&limit=1 counts 1.

Two separate defects found and deliberately not fixed here: /Search/Hints
ignores parentId, and OriginalTitle is never matched. Both filed.

`/Search/Hints` is two queries, and this port was doing neither. `SqlSearchProvider` scores every row whose folded `CleanName` holds the term, first arm winning: | score | condition | |---|---| | 100 | the whole name | | 80 | the front of it | | 75 | a word inside it (`term + " "`) | | 50 | anywhere at all | 80 beats 75, so `Skyfall` outranks `Above Sky Line`; and a name *ending* in the term scores 50, not 75 — no trailing space — which is why upstream puts `The Matrix` last for `matrix`. It cuts with `score DESC, id ASC` at `limit ?? 100`, then `SearchManager` re-reads those ids ordered by `SortName` and stably re-sorts by score. Net: **score DESC, SortName ASC**, and the cut happens *before* paging, so `TotalRecordCount` is the capped count. | term | upstream and now ours | before | |---|---|---| | `alien` | Alien, Aliens of London (1), Alien: Covenant, Alien: Earth, Alien: Romulus, … | three episodes first, the film fourth | | `matrix` | Reloaded, Resurrections, Revolutions, **The Matrix** | The Matrix first | | `love&limit=8` | total **8** | total **179** | | `star&limit=12` | total **12** | total **145** | **128 of 128** request variants are now byte-identical to upstream — 28 terms across bare, limited, paged, and type-filtered forms. Before, nearly all differed. Also fixed here: `Year`, `Folder` and `CollectionFolder` are excluded as upstream excludes them, a whitespace-only term is a 400 rather than the whole library, and a term that folds to nothing matches nothing. One existing test asserted `total=2` for `limit=1`. That was this port's own answer, not upstream's — verified live, `alien&limit=1` counts 1. Two separate defects found and deliberately not fixed here: `/Search/Hints` ignores `parentId`, and `OriginalTitle` is never matched. Both filed.
Sign in to join this conversation.
No description provided.