Skip to content

Comments

Add an improved backend for the Cause search#658

Open
danniel wants to merge 4 commits intomainfrom
feature/cause-search
Open

Add an improved backend for the Cause search#658
danniel wants to merge 4 commits intomainfrom
feature/cause-search

Conversation

@danniel
Copy link
Collaborator

@danniel danniel commented Feb 20, 2026

No description provided.

@danniel danniel requested a review from tudoramariei February 20, 2026 07:18
@greptile-apps
Copy link

greptile-apps bot commented Feb 20, 2026

Greptile Summary

Replaces NgoCauseMixedSearchMixin with new ImprovedCauseSearchMixin that adds exact match search with registration number lookup fallback before fuzzy search.

Key Changes:

  • Adds probable_registration_number() helper to detect and parse registration numbers (supports RO prefix and numeric-only formats)
  • New ImprovedCauseSearchMixin implements two-tier search: exact match first (by name or registration number), then fuzzy search if no exact matches found
  • Registration number search specifically targets main causes (is_main=True) associated with matching NGOs
  • Controlled by new ENABLE_CAUSE_SEARCH_EXACT_MATCH feature flag (defaults to True)
  • Applied to both SearchCausesApi and NgoListHandler views

Confidence Score: 4/5

  • Safe to merge with minor optimization opportunity
  • Code is well-structured with proper feature flag control and follows existing patterns, but has one non-critical performance issue using len() on QuerySet instead of .exists()
  • backend/donations/views/common/search.py - consider optimizing QuerySet evaluation on line 156

Important Files Changed

Filename Overview
backend/donations/views/common/search.py Adds probable_registration_number() helper and new ImprovedCauseSearchMixin with exact match fallback and registration number search
backend/donations/views/api.py Updates SearchCausesApi to use ImprovedCauseSearchMixin instead of NgoCauseMixedSearchMixin
backend/donations/views/site.py Updates NgoListHandler to use ImprovedCauseSearchMixin instead of NgoCauseMixedSearchMixin
backend/redirectioneaza/settings/feature_flags.py Adds ENABLE_CAUSE_SEARCH_EXACT_MATCH feature flag defaulting to True

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User Search Query] --> B[ImprovedCauseSearchMixin.get_search_results]
    B --> C{ENABLE_CAUSE_SEARCH_EXACT_MATCH?}
    C -->|Yes| D[Build Exact Match Filter]
    D --> E[name__icontains query]
    D --> F{Query looks like registration number?}
    F -->|Yes| G[probable_registration_number helper]
    G --> H{Starts with RO + numeric?}
    G --> I{Only numeric?}
    H -->|Yes| J[Extract numeric part]
    I -->|Yes| K[Use as-is]
    J --> L[Add filter: ngo__registration_number + is_main=True]
    K --> L
    F -->|No| M[Execute exact_causes query]
    L --> M
    E --> M
    M --> N{Has exact matches?}
    N -->|Yes| O[Return exact matches]
    N -->|No| P[Fall through to fuzzy search]
    C -->|No| P
    P --> Q[Build SearchVector + SearchQuery]
    Q --> R{ENABLE_CAUSE_SEARCH_WORD_SIMILARITY?}
    R -->|Yes| S[Use TrigramWordSimilarity threshold 0.4]
    R -->|No| T[Use TrigramSimilarity threshold 0.3]
    S --> U[Execute fuzzy_causes query]
    T --> U
    U --> V[Return fuzzy results]
    O --> W[Return to API/View]
    V --> W
Loading

Last reviewed commit: 4b5a501

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Copy link
Member

@tudoramariei tudoramariei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The most important thing is this comment
https://github.com/code4romania/redirectioneaza/pull/658/changes#r2832804852

and then check if the other things still make sense

# If the query looks like a registration number then also try to find the main causes owned by
# organisations which have that registration number
if registration_number:
query_filter = query_filter | (Q(ngo__registration_number=registration_number) & Q(is_main=True))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we remove the initial query_filter?
If we have a registration number, it feels redundant to search in the name for it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't know if we have a real registration number or just some plain text.

if exact_causes.count():
return exact_causes

search_vector: SearchVector = ConfigureSearch.vector(("name",), language_code)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the vector be configured by what we're searching?
I think it should be changed to the registration number if we're going on that path.

registration_number = probable_registration_number(query)
# If the query looks like a registration number then also try to find the main causes owned by
# organisations which have that registration number
if registration_number:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Search is a bit annoying, but we should take into account one path if we get a registration number (CIF) and a different one if it isn't that.
It seems a bit more straightforward if it's a registration number and we may need to just run a filter with Q(ngo__registration_number=registration_number) & Q(is_main=True) and not much more (we probably don't need search vectors or other things.

In this if statement I'd branch out things and directly return Cause.objects.filter(Q(ngo__registration_number=registration_number) & Q(is_main=True)) or something like that
Simplifies the flow and leaves a clearer trail to follow once you only have the name.

@danniel danniel requested a review from tudoramariei February 20, 2026 12:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants