Skip to main content

Combining AI Search with Structured Filters

AI search and manual filters work together. AI-extracted filters fill gaps, but explicit params always take priority.

Merge Logic

AI extracts:     { city: "Goa", adults: 6, petFriendly: true }
Explicit params: { channelId: "B2C", adults: 4 }
─────────────────────────────────────────────────
Merged: { channelId: "B2C", city: "Goa", adults: 4, petFriendly: true }
↑ explicit wins

Use Cases

User types a query, then adjusts filters

  1. User: "Villas in Goa for 6 people"
  2. Frontend calls /ai-search/intent → gets city: Goa, adults: 6, propertyType: Villa
  3. Frontend auto-fills filter UI
  4. User changes adults to 4 and adds "pet-friendly"
  5. Frontend calls /ai-search with:
    {
    "query": "Villas in Goa for 6 people",
    "rawParams": [
    { "filterName": "adults", "filterValues": ["4"] },
    { "filterName": "petFriendly", "filterValues": ["true"] }
    ]
    }
  6. Merged: city=Goa (AI) + adults=4 (explicit) + petFriendly=true (explicit) + propertyType=Villa (AI)

Search bar + filter chips together

The AI search bar and the filter chips are not mutually exclusive. The AI understands intent, the filters refine it.

What Happens Internally

1. ListingRagSearchService.search(query)
→ Vector similarity + LLM rerank → ListingSearchIntent

2. mergeIntentWithParams(intent, explicitParams)
→ AI listingIds become "listingId" rawParam (scopes to relevant listings)
→ AI checkInDate, city, etc. fill missing rawParams
→ Explicit params override on conflict

3. MultiListingSearchService.search(mergedRequest)
→ Standard listing search runs with merged filters
→ PricingContextService applies traffic context
→ Full pricing, offers, cancellation plans