feat(search): implement keyword→tag resolution in NlQueryParserService
Keywords that substring-match the tag taxonomy become OR-union tag filters; non-matching keywords stay as FTS text. Resolved tags surface in the NlQueryInterpretation as TagHint objects with effective colours. The rawQuery fallback is now guarded by hadStructuredMatch to prevent double-apply when all keywords resolve. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -441,4 +441,41 @@ class NlQueryParserServiceTest {
|
||||
|
||||
assertThat(resp.interpretation().keywordsApplied()).isTrue();
|
||||
}
|
||||
|
||||
// --- Tag resolution helpers ---
|
||||
|
||||
private Tag tag(UUID id, String name) {
|
||||
return Tag.builder().id(id).name(name).build();
|
||||
}
|
||||
|
||||
private Tag tag(UUID id, String name, String color) {
|
||||
return Tag.builder().id(id).name(name).color(color).build();
|
||||
}
|
||||
|
||||
private TagHint tagHint(UUID id, String name, String color) {
|
||||
return new TagHint(id, name, color);
|
||||
}
|
||||
|
||||
private static final UUID T1 = UUID.fromString("00000000-0000-0000-0001-000000000001");
|
||||
|
||||
// --- 24. Single keyword resolves to one tag → tag filter applied ---
|
||||
|
||||
@Test
|
||||
void search_singleKeywordResolvesToTag_appliesTagFilter() {
|
||||
Tag hochzeit = tag(T1, "Hochzeit");
|
||||
when(ollamaClient.parse(anyString()))
|
||||
.thenReturn(extraction(List.of(), "any", null, null, List.of("Hochzeit")));
|
||||
when(tagService.findByNameContaining("Hochzeit")).thenReturn(List.of(hochzeit));
|
||||
|
||||
NlSearchResponse resp = service.search("Briefe über Hochzeit", PAGE);
|
||||
|
||||
ArgumentCaptor<SearchFilters> cap = ArgumentCaptor.forClass(SearchFilters.class);
|
||||
verify(documentService).searchDocuments(cap.capture(), any(), any(), any());
|
||||
assertThat(cap.getValue().tags()).containsExactly("Hochzeit");
|
||||
assertThat(cap.getValue().tagOperator()).isEqualTo(TagOperator.OR);
|
||||
assertThat(resp.interpretation().resolvedTags()).hasSize(1);
|
||||
assertThat(resp.interpretation().resolvedTags().get(0).name()).isEqualTo("Hochzeit");
|
||||
assertThat(resp.interpretation().tagsApplied()).isTrue();
|
||||
assertThat(cap.getValue().text()).isNull();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user