From f2ab8d3740a0407116ad98ea36cc14642268aefb Mon Sep 17 00:00:00 2001 From: Cameron Cordes Date: Sun, 14 Jun 2026 02:25:24 -0400 Subject: [PATCH] Unified search: use ANY-mode tag matching, not ALL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- src/unified_search.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/unified_search.rs b/src/unified_search.rs index 9eea405..555773c 100644 --- a/src/unified_search.rs +++ b/src/unified_search.rs @@ -264,13 +264,15 @@ pub async fn unified_search( let mut allowed_hashes: HashSet = 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> = 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,