Prompt

How do I set up candidate search and filtering software for saved searches and job alerts on our marketplace?

Latest observation

Jul 26, 2026 · OpenAI APIWeb search: off

To set up candidate search and filtering for saved searches and job alerts on a marketplace, you want to design it as a search + query persistence + alerting pipeline.

Here’s a practical way to structure it.


1) Define the core use cases

Typical marketplace scenarios:

  • Buyers/employers search candidates
  • They save a search with filters like location, skills, availability, experience, rate
  • They get alerts when new candidates match
  • They revisit saved searches later and see updated results

So the system needs to support:

  • Fast filtering across many candidate profiles
  • Persisted search definitions
  • Notification generation when matching profiles/jobs appear
  • De-duplication and frequency controls

2) Model the data

You’ll usually need these entities:

Candidate profile

Store structured attributes for filtering.

Example:

  • id
  • name
  • headline
  • location
  • geo_point
  • skills[]
  • years_experience
  • availability
  • employment_type
  • hourly_rate
  • industry
  • updated_at
  • is_active

Saved search

Store the search criteria as a query object.

Example:

  • id
  • user_id
  • name
  • criteria_json
  • sort_json
  • created_at
  • updated_at
  • alert_enabled
  • alert_frequency
    • immediate
    • daily
    • weekly
  • last_run_at
  • last_alerted_at

Search alert history

Track what has already been sent.

Example:

  • id
  • saved_search_id
  • candidate_id
  • matched_at
  • alert_batch_id

This prevents duplicate alerts.


3) Build a flexible filtering schema

Your search filters should map to a machine-readable structure.

Example search criteria JSON:

{
  "location": ["San Francisco", "Remote"],
  "skills": ["React", "Node.js"],
  "years_experience_min": 5,
  "availability": ["full_time"],
  "rate_max": 120,
  "updated_within_days": 14
}

For advanced searching, support:

  • AND / OR groups
  • range filters
  • multi-select filters
  • location radius
  • keyword search
  • boosting/ranking

4) Use a search index, not just the transactional DB

For anything beyond very small scale, use a search engine like:

  • Elasticsearch
  • OpenSearch
  • Meilisearch
  • Algolia

Why:

  • Fast faceted filtering
  • Full-text search
  • Ranking
  • Better alert matching
  • Support for partial matches and complex queries

You can still keep the source of truth in PostgreSQL/MySQL, and sync candidate profiles into the search index.


5) Create the search API

You’ll typically need endpoints like:

Search candidates

GET /candidates/search

Query example:

/candidates/search?skills=React,Node.js&location=Remote&min_experience=5

Save search

POST /saved-searches

Payload:

{
  "name": "Senior React remote candidates",
  "criteria": {
    "skills": ["React"],
    "location": ["Remote"],
    "years_experience_min": 5
  },
  "alert_enabled": true,
  "alert_frequency": "daily"
}

List saved searches

GET /saved-searches

Update/delete saved search

PATCH /saved-searches/:id DELETE /saved-searches/:id


6) Generate alerts from saved searches

There are two common patterns.

A. Scheduled batch alerts

Run a job every X minutes/hours/day:

  1. Fetch enabled saved searches
  2. Re-run each search against the index
  3. Compare current matches to previously alerted candidates
  4. Send notifications for new matches only

Best for:

  • Daily/weekly digests
  • Predictable load
  • Easier deduplication

B. Real-time matching

When a new candidate is created or updated:

  1. Index the candidate
  2. Evaluate saved searches that may match
  3. Send immediate alerts

Best for:

  • “Instant alerts”
  • Low-latency UX

In practice, many systems use both:

  • Immediate for premium/high-priority users
  • Batch for most users

7) Use a matching engine for alerts

For each saved search, you need a way to check whether a candidate matches.

Approach:

  • Store the saved search as structured filters
  • Convert that to a search query
  • Execute query against the index
  • Return matching candidate IDs

If doing real-time matching at scale, optimize by:

  • Precomputing normalized fields
  • Using inverted indexes for skills/tags
  • Partitioning searches by geography or category
  • Only evaluating likely candidate/search pairs

8) Deduplicate notifications

Without deduplication, users will get spammed.

Track:

  • Which candidate was already sent for which saved search
  • When the search was last run
  • Whether the candidate profile changed enough to notify again

Common rules:

  • Only alert on new matches
  • Don’t repeat the same candidate within N days
  • For updated profiles, alert only if key fields changed

9) Add ranking and relevance

Search results should not be purely boolean.

You may want to rank by:

  • Skills match score
  • Distance from desired location
  • Recency of profile update
  • Completeness of profile
  • Availability match

Example ranking logic:

  • Exact skill match: +10
  • Remote match: +5
  • Updated within 7 days: +3
  • Close location: +2

This makes saved searches and alerts more useful.


10) Handle permissions and privacy

Candidate search often involves privacy concerns.

Make sure to enforce:

  • Visibility settings on profiles
  • Role-based access
  • Consent for alerts if required
  • Redaction of sensitive data
  • Audit logs for who searched whom

If candidates can opt out of being discoverable, your indexing logic must respect that.


11) Build the notification system

Once matches are found, send alerts via:

  • Email
  • In-app notifications
  • Push notifications
  • SMS, if appropriate

Notification payload should include:

  • Search name
  • Candidate summary
  • Why it matched
  • Link to view details

Example:

3 new candidates matched your saved search “Senior React remote”.


12) Operational concerns

Performance

  • Index profiles asynchronously
  • Cache common searches
  • Use pagination and result caps

Freshness

  • Reindex changed profiles quickly
  • Use event-driven updates if possible

Scalability

  • Queue search evaluation jobs
  • Batch alert processing
  • Separate indexing from API traffic

Observability

Track:

  • Search latency
  • Match counts
  • Alert send rate
  • Email open/click rate
  • Failure rate in indexing

13) Recommended implementation stack

A common stack might be:

  • Backend: Node.js, Python, Java, or Go
  • Database: PostgreSQL
  • Search: OpenSearch / Elasticsearch
  • Queue: SQS, RabbitMQ, Kafka, or Redis queue
  • Notifications: SendGrid, Twilio, Firebase, in-app table
  • Scheduler: Cron, Celery beat, Sidekiq, Quartz, etc.

14) Example architecture

  1. Candidate updates profile
  2. App saves profile in DB
  3. Event sent to queue
  4. Indexer updates search index
  5. Alert worker checks matching saved searches
  6. New matches stored in alert history
  7. Notification sent to user

15) Minimum viable version

If you want a simpler first version:

  1. Store saved searches as JSON in your DB
  2. Run scheduled jobs every hour/day
  3. Query candidates using SQL filters or search engine
  4. Store sent candidate IDs per search
  5. Send email digest alerts

That’s enough to launch, then optimize later.


If you want, I can also provide:

  1. a database schema,
  2. API endpoint design, or
  3. a sample implementation in Python/Node.js.

Observation history

See 1 earlier observation

Create a free Obsurfable account to unlock historical responses, model comparisons, and deeper brand intelligence.

How did Obsurfable measure this prompt?

Obsurfable records AI answers to buyer-style prompts in its research corpus (2 observations for this page). Metrics are distributions over observations, not a single static ranking.

Which AI systems does Obsurfable collect answers from?

OpenAI, ChatGPT, Google, Gemini, Google AI Mode, Anthropic, Claude, Perplexity, Grok, DeepSeek, Mistral, Copilot, and Meta AI.