Unified search: use ANY-mode tag matching, not ALL

ALL-mode over-constrains NL queries — the model maps several query words to
tags and few photos carry every one, zeroing the candidate set. Switch to
ANY (a photo matches if it has any named tag); the semantic CLIP ranking
provides precision within that pool. Exclude tags still filter out.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cameron Cordes
2026-06-14 02:25:24 -04:00
parent 6e5898e766
commit f2ab8d3740
+5 -3
View File
@@ -264,13 +264,15 @@ pub async fn unified_search<TagD: TagDao>(
let mut allowed_hashes: HashSet<String> = HashSet::new();
if has_struct {
// Tag membership set (rel_path only — same cross-library imprecision
// as the existing /photos tag listing). ALL-mode: the photo must
// carry every named tag.
// as the existing /photos tag listing). ANY-mode: a photo matches if
// it carries any of the named tags. ALL-mode over-constrains NL
// queries (the model maps several words to tags and few photos carry
// them all); the semantic term does the precision work instead.
let tag_set: Option<HashSet<String>> = if sq.tag_ids.is_empty() {
None
} else {
let mut dao = tag_dao.lock().expect("tag dao");
match dao.get_files_with_all_tag_ids(
match dao.get_files_with_any_tag_ids(
sq.tag_ids.clone(),
sq.exclude_tag_ids.clone(),
&ctx,