Skip to content

NGO search exact match#652

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

NGO search exact match#652
danniel wants to merge 4 commits intomainfrom
feature/exact-match-search

Conversation

@danniel
Copy link
Collaborator

@danniel danniel commented Feb 16, 2026

Summary by CodeRabbit

  • New Features
    • Improved NGO search with better exact-match handling for longer or precise queries.
    • Added support for searching organizations by registration numbers (numeric and official codes).
    • Search now favors direct cause matches when available and falls back to broader fuzzy results for more relevant results.

@danniel danniel requested a review from tudoramariei February 16, 2026 19:43
@coderabbitai
Copy link

coderabbitai bot commented Feb 16, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Adds exact-match NGO search support: a helper to detect registration numbers, a new NgoExactSearchMixin for exact name/registration filtering, and conditional use of exact vs. fuzzy search in NgoCauseMixedSearchMixin controlled by a new feature flag.

Changes

Cohort / File(s) Summary
NGO search logic
backend/donations/views/common/search.py
Added `probably_registration_number(query: str) -> str
Feature flag
backend/redirectioneaza/settings/feature_flags.py
Added ENABLE_NGO_SEARCH_EXACT_MATCH feature flag (env-driven, default True) to toggle exact-match NGO search.

Sequence Diagram

sequenceDiagram
    participant Client as Client
    participant Mixin as NgoCauseMixedSearchMixin
    participant Flags as FeatureFlag
    participant Exact as NgoExactSearchMixin
    participant Fuzzy as NgoSearchMixin
    participant DB as Database

    Client->>Mixin: get_search_results(query)
    Mixin->>Flags: check ENABLE_NGO_SEARCH_EXACT_MATCH

    alt Exact match enabled & query qualifies
        Flags-->>Mixin: True
        Mixin->>Exact: get_search_results(query)
        Exact->>DB: filter NGOs by name__icontains OR registration_number
        DB-->>Exact: exact_ngos
        Exact->>DB: filter causes by exact_ngos
        DB-->>Exact: exact_causes
        Exact-->>Mixin: exact_causes
        Mixin-->>Client: return exact_causes (if any)
    else Fallback to fuzzy flow
        Flags-->>Mixin: False or query not qualifying
        Mixin->>Fuzzy: get_search_results(query)
        Fuzzy->>DB: fuzzy match NGOs and causes
        DB-->>Fuzzy: fuzzy_ngos, fuzzy_causes
        Fuzzy-->>Mixin: fuzzy results
        Mixin->>DB: direct cause search (searched_causes)
        DB-->>Mixin: searched_causes
        Mixin-->>Client: return searched_causes + fuzzy_causes
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I sniffed the query, sharp and bright,
Found numbers twinkling in the night,
Exact or fuzzy — flags decide,
I hop between results with pride,
Hooray for searches done just right! 🎉

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'NGO search exact match' clearly and concisely summarizes the main change: implementing exact match search functionality for NGOs.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/exact-match-search

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link

greptile-apps bot commented Feb 16, 2026

Greptile Summary

Adds exact match search capability for NGOs, prioritizing exact name matches and registration number lookups over fuzzy search. Introduces NgoExactSearchMixin that performs case-insensitive name matching and registration number lookups (with "RO" prefix stripping), integrated into NgoCauseMixedSearchMixin behind a feature flag.

Key changes:

  • New NgoExactSearchMixin class for exact/simple matching on NGO names and registration numbers
  • Modified NgoCauseMixedSearchMixin to try exact match first (when enabled), fallback to fuzzy search if no results
  • Added ENABLE_NGO_SEARCH_EXACT_MATCH feature flag (defaults to True)
  • Exact match triggered when query has numeric chars after position 2 OR query length > 20

Issues found:

  • Logic mismatch: line 151 condition query[2:].isnumeric() triggers for any 2-char prefix (e.g., "AB12345"), but NgoExactSearchMixin only strips "RO" prefix
  • Typo in comment on line 80

Confidence Score: 2/5

  • This PR has a logic bug that needs fixing before merge
  • Score reflects a critical logic mismatch where the trigger condition for exact match (line 151) doesn't align with the actual search behavior in NgoExactSearchMixin. This could cause unexpected behavior when users search with queries like "AB12345" - the system would trigger exact match but wouldn't properly handle the prefix stripping. Additionally, there's a typo in a comment that should be corrected.
  • Pay close attention to backend/donations/views/common/search.py line 151 - the condition needs to be fixed to match the actual search logic

Important Files Changed

Filename Overview
backend/donations/views/common/search.py Added NgoExactSearchMixin for exact matching and integrated it into mixed search with feature flag; logic mismatch between trigger condition and actual search behavior found
backend/redirectioneaza/settings/feature_flags.py Added ENABLE_NGO_SEARCH_EXACT_MATCH feature flag with default value True

Flowchart

flowchart TD
    A[Search Query] --> B{Feature Flag Enabled?}
    B -->|No| G[Fuzzy Search Only]
    B -->|Yes| C{Trigger Exact Match?}
    C -->|No| G
    C -->|Yes| D[NgoExactSearchMixin]
    D --> E{Results Found?}
    E -->|Yes| F[Return Exact Results]
    E -->|No| G
    G --> H[NgoSearchMixin Fuzzy]
    G --> I[CauseSearchMixin]
    H --> J[Union Results]
    I --> J
    J --> K[Return Combined Results]
Loading

Last reviewed commit: 5740c94

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.

2 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
Before applying any fix, first verify the finding against the current code and
decide whether a code change is actually needed. If the finding is not valid or
no change is required, do not modify code for that item and briefly explain why
it was skipped.

In `@backend/donations/views/common/search.py`:
- Line 80: Fix the typo in the inline comment in search.py (the comment that
reads "Try to guess is the user is looking for a registration number") by
changing "is" to "if" so it reads "Try to guess if the user is looking for a
registration number"; update the comment in the same location within the
relevant function or block where that line appears.
- Around line 155-156: The truthiness check "if exact_causes:" forces evaluation
of the entire queryset; change it to use the lightweight EXISTS check by
replacing that condition with "if exact_causes.exists():" so the code performs
an efficient EXISTS query and still returns the queryset (exact_causes) for the
paginated NgoListHandler (paginate_by = 8).
🧹 Nitpick comments (1)
🤖 Fix all nitpicks with AI agents
Before applying any fix, first verify the finding against the current code and
decide whether a code change is actually needed. If the finding is not valid or
no change is required, do not modify code for that item and briefly explain why
it was skipped.

In `@backend/donations/views/common/search.py`:
- Around line 155-156: The truthiness check "if exact_causes:" forces evaluation
of the entire queryset; change it to use the lightweight EXISTS check by
replacing that condition with "if exact_causes.exists():" so the code performs
an efficient EXISTS query and still returns the queryset (exact_causes) for the
paginated NgoListHandler (paginate_by = 8).
backend/donations/views/common/search.py (1)

155-156: Consider using .exists() for more efficient queryset check with pagination.

Using if exact_causes: evaluates the entire queryset and caches all results. Since NgoListHandler uses pagination (paginate_by = 8), using .exists() would be more efficient—it runs a lightweight EXISTS query, and only the paginated subset is fetched later.

Proposed fix
-        if exact_causes:
+        if exact_causes.exists():
             return exact_causes
🤖 Prompt for AI Agents
Before applying any fix, first verify the finding against the current code and
decide whether a code change is actually needed. If the finding is not valid or
no change is required, do not modify code for that item and briefly explain why
it was skipped.
In `@backend/donations/views/common/search.py` around lines 155 - 156, The
truthiness check "if exact_causes:" forces evaluation of the entire queryset;
change it to use the lightweight EXISTS check by replacing that condition with
"if exact_causes.exists():" so the code performs an efficient EXISTS query and
still returns the queryset (exact_causes) for the paginated NgoListHandler
(paginate_by = 8).

@danniel
Copy link
Collaborator Author

danniel commented Feb 16, 2026

Attempt to fix #622

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.

1 participant