Search hints ignore the library they were asked about #55

Closed
opened 2026-08-03 23:37:10 +02:00 by Claude · 1 comment
Collaborator

/Search/Hints ignores parentId.

Searching within a library returns hits from every library. Upstream scopes the
search by ParentId OR AncestorIds; this server drops the parameter.

Not fixed alongside the ranking work because the shared narrowing this server
uses rewrites a library parent into TopParentId, which is a visibly different
set: the music library has only 73 AncestorIds rows, so upstream answers
parentId=<music>&searchTerm=love with 0 where a TopParentId scope
answers with 10. Matching upstream needs its own narrowing path rather than the
one every other route shares.

`/Search/Hints` ignores `parentId`. Searching within a library returns hits from every library. Upstream scopes the search by `ParentId OR AncestorIds`; this server drops the parameter. Not fixed alongside the ranking work because the shared narrowing this server uses rewrites a library parent into `TopParentId`, which is a visibly different set: the music library has only 73 `AncestorIds` rows, so upstream answers `parentId=<music>&searchTerm=love` with **0** where a `TopParentId` scope answers with 10. Matching upstream needs its own narrowing path rather than the one every other route shares.
Author
Collaborator

A search is scoped to the library it was asked about.

Upstream does it in two passes, and they are not the same query.
SqlSearchProvider.ApplyParentFilter picks candidates by
ParentId == pid || Parents.Any(p => p.ParentItemId == pid); then
SearchManager re-queries those ids with ParentId = pid, Recursive = true, and
SetTopParentIdsOrAncestors clears ParentId, replacing it with
TopParentIds for a library or AncestorIds for anything else. The answer is
the intersection.

That is why the narrowing every other route shares is wrong here: it is the
TopParentId half alone. Measured — a MusicAlbum parent yields 4 tracks from
the first pass and 0 after the second, and upstream answers 0.

request before after upstream
love in Movies 100 (every library) 3 3
love in Music 100 0 0
love in Shows 100 75 75
love under an album 100 0 0

Verified live afterwards, ordering as well as counts.

No regression to the ranking: 171 request variants and a 236-variant randomized
sweep over real parents and terms — including %, _, ', CJK, Cyrillic and
deep paging — come back identical, and the differential harness reports the same
per-scenario numbers as before the change.

Found and not fixed: /Search/Hints?includeMedia=false is ignored here where
upstream answers nothing. Pre-existing and orthogonal; filed separately.

A search is scoped to the library it was asked about. Upstream does it in two passes, and they are not the same query. `SqlSearchProvider.ApplyParentFilter` picks candidates by `ParentId == pid || Parents.Any(p => p.ParentItemId == pid)`; then `SearchManager` re-queries those ids with `ParentId = pid, Recursive = true`, and `SetTopParentIdsOrAncestors` **clears** `ParentId`, replacing it with `TopParentIds` for a library or `AncestorIds` for anything else. The answer is the intersection. That is why the narrowing every other route shares is wrong here: it is the `TopParentId` half alone. Measured — a `MusicAlbum` parent yields 4 tracks from the first pass and 0 after the second, and upstream answers 0. | request | before | after | upstream | |---|---|---|---| | `love` in Movies | 100 (every library) | **3** | 3 | | `love` in Music | 100 | **0** | 0 | | `love` in Shows | 100 | **75** | 75 | | `love` under an album | 100 | **0** | 0 | Verified live afterwards, ordering as well as counts. No regression to the ranking: 171 request variants and a 236-variant randomized sweep over real parents and terms — including `%`, `_`, `'`, CJK, Cyrillic and deep paging — come back identical, and the differential harness reports the same per-scenario numbers as before the change. Found and not fixed: `/Search/Hints?includeMedia=false` is ignored here where upstream answers nothing. Pre-existing and orthogonal; filed separately.
Sign in to join this conversation.
No description provided.