Vector Search (sdk.ai.search)
Add semantic search to your application in 2 lines of code. No vector database setup, no embedding management—just ingest and search.
Quick Start
import { AerostackServer } from '@aerostack/sdk';
const sdk = new AerostackServer(env);
// Ingest content
await sdk.ai.search.ingest("Our office is located in San Francisco", {
type: "faq",
metadata: { category: "locations" }
});
// Search semantically
const results = await sdk.ai.search.query("Where is the office?");
console.log(results[0].content);
// "Our office is located in San Francisco"Core Concepts
Custom Types
Define your own data types for any use case: recipe, job_listing, property, course, etc. The system is completely flexible.
Metadata Filtering
Add structured metadata to enable precise filtering alongside semantic search.
Multi-Language Support
Choose English (default, faster) or Multilingual (100+ languages).
API Reference
ingest(content, options)
Add content to the search index.
await sdk.ai.search.ingest(content: string, {
id?: string, // Auto-generated UUID if omitted
type: string, // Your custom type
metadata?: Record<string, any> // Filterable fields
});Example:
await sdk.ai.search.ingest(
"Mediterranean Quinoa Bowl with fresh vegetables and tahini dressing",
{
id: "recipe-001",
type: "recipe",
metadata: {
cuisine: "mediterranean",
difficulty: "easy",
prep_time_mins: 25,
dietary: ["vegetarian", "gluten-free"]
}
}
);query(text, options)
Search content semantically with optional filters.
const results = await sdk.ai.search.query(text: string, {
topK?: number, // Number of results (default: 5)
types?: string[], // Filter by types
filter?: Record<string, any> // Metadata filters
});Returns:
interface SearchResult {
id: string;
content: string;
score: number; // 0-1 similarity score
type: string;
metadata: Record<string, any>;
}delete(id) & deleteByType(type)
Remove content from the index.
await sdk.ai.search.delete("recipe-001");
await sdk.ai.search.deleteByType("recipe");listTypes()
Get all data types in your project.
const types = await sdk.ai.search.listTypes();
// Returns: [{ type: 'recipe', count: 127 }, { type: 'article', count: 45 }]configure(options)
Set project-wide search settings (call once).
await sdk.ai.search.configure({
model: 'multilingual' // or 'english' (default)
});update(id, content, options?)
Update an existing indexed item by re-ingesting with the same ID. The Vectorize upsert is idempotent — this replaces the vector and metadata without creating a duplicate.
await sdk.ai.search.update('article-123', 'Updated content here...', {
type: 'blog_post',
metadata: { updated_at: Date.now(), version: 2 }
});get(id)
Retrieve a specific indexed item by ID.
const { result, exists } = await sdk.ai.search.get('article-123');
if (exists) {
console.log(result.content);
console.log(result.metadata);
}count(type?)
Count total indexed items, optionally filtered by type.
// Total count across all types
const { count: total } = await sdk.ai.search.count();
console.log(`${total} items indexed`);
// Count by type
const { count: articles } = await sdk.ai.search.count('blog_post');
const { count: recipes } = await sdk.ai.search.count('recipe');Real-World Examples
1. Recipe Search Platform
// Ingest recipes
for (const recipe of recipes) {
await sdk.ai.search.ingest(
`${recipe.name}. ${recipe.description}. Ingredients: ${recipe.ingredients.join(', ')}. Instructions: ${recipe.instructions}`,
{
id: recipe.id,
type: 'recipe',
metadata: {
cuisine: recipe.cuisine,
difficulty: recipe.difficulty,
prep_time_mins: recipe.prepTime,
cook_time_mins: recipe.cookTime,
dietary: recipe.dietary, // ['vegan', 'gluten-free']
rating: recipe.averageRating
}
}
);
}2. Job Board
// Ingest job listings
await sdk.ai.search.ingest(
`${job.title} at ${job.company}. ${job.description}. Required skills: ${job.requiredSkills.join(', ')}. Benefits: ${job.benefits}`,
{
id: job.id,
type: 'job_listing',
metadata: {
company: job.company,
location: job.location,
remote: job.isRemote,
employment_type: job.type, // 'full-time', 'contract'
salary_min: job.salaryRange.min,
salary_max: job.salaryRange.max,
experience_level: job.experienceLevel,
skills: job.requiredSkills,
posted_date: job.postedAt
}
}
);3. E-Learning Platform
// Ingest courses
await sdk.ai.search.ingest(
`${course.title}. ${course.description}. Topics covered: ${course.topics.join(', ')}. Learning outcomes: ${course.outcomes.join(', ')}`,
{
id: course.id,
type: 'course',
metadata: {
category: course.category,
level: course.level, // 'beginner', 'intermediate', 'advanced'
duration_hours: course.duration,
instructor: course.instructor,
rating: course.rating,
price: course.price,
language: course.language,
skills: course.skillsTaught
}
}
);4. Real Estate Listings
// Ingest property listings
await sdk.ai.search.ingest(
`${property.title}. ${property.description}. Features: ${property.features.join(', ')}. Neighborhood: ${property.neighborhood}`,
{
id: property.id,
type: 'property',
metadata: {
property_type: property.type, // 'house', 'apartment', 'condo'
bedrooms: property.bedrooms,
bathrooms: property.bathrooms,
sqft: property.squareFeet,
price: property.price,
city: property.city,
neighborhood: property.neighborhood,
features: property.features, // ['pool', 'garage', 'garden']
year_built: property.yearBuilt,
status: property.status // 'for_sale', 'for_rent'
}
}
);5. Support Documentation / FAQ
// Ingest help articles
await sdk.ai.search.ingest(
`Q: ${article.question}\nA: ${article.answer}`,
{
id: article.id,
type: 'support_article',
metadata: {
category: article.category, // 'billing', 'account', 'technical'
subcategory: article.subcategory,
views: article.viewCount,
helpful_votes: article.helpfulVotes,
updated_at: article.updatedAt
}
}
);6. E-Commerce Products
// Ingest products
await sdk.ai.search.ingest(
`${product.name}. ${product.description}. Specifications: ${product.specs}`,
{
id: product.id,
type: 'product',
metadata: {
category: product.category,
brand: product.brand,
price: product.price,
in_stock: product.inStock,
rating: product.averageRating,
review_count: product.reviewCount,
tags: product.tags,
color: product.color,
size: product.size
}
}
);7. Blog / Content Platform
// Ingest blog posts
await sdk.ai.search.ingest(
`${post.title}. ${post.excerpt}. ${post.content}`,
{
id: post.id,
type: 'blog_post',
metadata: {
author: post.author,
category: post.category,
tags: post.tags,
published_at: post.publishedAt,
read_time_mins: post.readTime,
views: post.viewCount
}
}
);8. Event Management
// Ingest events
await sdk.ai.search.ingest(
`${event.name}. ${event.description}. Speakers: ${event.speakers.join(', ')}. Topics: ${event.topics.join(', ')}`,
{
id: event.id,
type: 'event',
metadata: {
category: event.category, // 'conference', 'workshop', 'webinar'
format: event.format, // 'in-person', 'virtual', 'hybrid'
start_date: event.startDate,
end_date: event.endDate,
location: event.location,
ticket_price: event.ticketPrice,
capacity: event.capacity,
spots_remaining: event.spotsRemaining,
tags: event.tags
}
}
);9. Restaurant / Menu Items
// Ingest menu items
await sdk.ai.search.ingest(
`${item.name}. ${item.description}. Ingredients: ${item.ingredients.join(', ')}`,
{
id: item.id,
type: 'menu_item',
metadata: {
restaurant: item.restaurantId,
category: item.category, // 'appetizer', 'main', 'dessert'
cuisine: item.cuisine,
price: item.price,
spice_level: item.spiceLevel,
dietary: item.dietary, // ['vegetarian', 'gluten-free']
popular: item.orderCount > 100,
rating: item.rating
}
}
);10. Medical / Health Resources
// Ingest health articles
await sdk.ai.search.ingest(
`${article.title}. ${article.summary}. Symptoms: ${article.symptoms.join(', ')}. Treatments: ${article.treatments.join(', ')}`,
{
id: article.id,
type: 'health_article',
metadata: {
category: article.category, // 'nutrition', 'fitness', 'mental_health'
condition: article.condition,
reviewed_by: article.reviewer,
last_updated: article.lastUpdated,
evidence_level: article.evidenceLevel, // 'high', 'moderate', 'low'
audience: article.audience // 'general', 'professional'
}
}
);Advanced Filtering
Comparison Operators
// Greater than / Less than
await sdk.ai.search.query("affordable products", {
types: ['product'],
filter: {
price: { $lte: 50 }, // Less than or equal
rating: { $gte: 4.0 } // Greater than or equal
}
});
// Range queries
await sdk.ai.search.query("mid-size sedan", {
types: ['car'],
filter: {
price: { $gte: 20000, $lte: 35000 },
year: { $gte: 2020 }
}
});Array Filters
// Contains (any match)
await sdk.ai.search.query("vegetarian recipe", {
types: ['recipe'],
filter: {
dietary: { $contains: 'vegetarian' }
}
});
// Contains all
await sdk.ai.search.query("full-stack developer", {
types: ['job_listing'],
filter: {
skills: { $containsAll: ['React', 'Node.js', 'PostgreSQL'] }
}
});Multi-Type Search
// Search across multiple types
const results = await sdk.ai.search.query("javascript tutorial", {
types: ['blog_post', 'course', 'video'],
topK: 20
});Multi-Language Setup
Switch to multilingual embeddings for 100+ language support:
await sdk.ai.search.configure({
model: 'multilingual'
});
// Now ingest and search in any language
await sdk.ai.search.ingest("Cómo hacer paella valenciana", {
type: 'recipe',
metadata: { language: 'es', cuisine: 'spanish' }
});
const results = await sdk.ai.search.query("paella recipe", {
types: ['recipe']
});
// Works across languages!English model: Faster, lower cost, optimized for English content.
Multilingual model: Supports 100+ languages, cross-language search.
Best Practices
1. Content Formatting
Structure your content for better search results:
// ✅ Good: Rich, descriptive content
await sdk.ai.search.ingest(
`${product.name}. ${product.description}. Key features: ${features.join(', ')}. Use cases: ${useCases.join(', ')}`,
{ type: 'product', metadata: {...} }
);
// ❌ Avoid: Minimal content
await sdk.ai.search.ingest(product.name, { type: 'product' });2. Metadata Design
Use metadata for precise filtering:
// ✅ Good: Structured, filterable metadata
metadata: {
category: 'electronics',
price: 599,
in_stock: true,
rating: 4.5
}
// ❌ Avoid: Putting filterable data only in content
content: "Price: $599, In Stock, 4.5 stars"3. Type Naming
Use clear, consistent type names:
// ✅ Good
type: 'job_listing'
type: 'blog_post'
type: 'support_article'
// ❌ Avoid
type: 'jobs'
type: 'post'
type: 'help'Quotas & Limits
| Plan | Ingest/month | Searches/month |
|---|---|---|
| Free | 1,000 items | 10,000 searches |
| Pro | 50,000 items | 100,000 searches |
| Enterprise | Unlimited | Unlimited |
Quota exceeded errors will return HTTP 429. Monitor usage in your Admin dashboard.
Performance Tips
- Batch ingestion: Ingest multiple items in parallel for faster indexing
- topK limits: Start with
topK: 5-10for faster searches - Metadata first: Use metadata filters before semantic search when possible
- Content length: Keep content between 100-1000 characters for optimal results