Spaces:
Build error
Build error
Invalid JSON: Unexpected token '/', "// OpenSea"... is not valid JSON
| // OpenSearch Index Mapping for Vendor Search | |
| // Supports faceted search: category, district, price range, rating, and full-text | |
| PUT /vendors | |
| { | |
| "settings": { | |
| "number_of_shards": 2, | |
| "number_of_replicas": 1, | |
| "analysis": { | |
| "analyzer": { | |
| "wedding_search": { | |
| "type": "custom", | |
| "tokenizer": "standard", | |
| "filter": ["lowercase", "asciifolding", "stop", "snowball"] | |
| } | |
| } | |
| } | |
| }, | |
| "mappings": { | |
| "properties": { | |
| "id": { "type": "keyword" }, | |
| "businessName": { "type": "text", "analyzer": "wedding_search", "fields": { "keyword": { "type": "keyword" } } }, | |
| "categoryId": { "type": "keyword" }, | |
| "categoryName": { "type": "keyword" }, | |
| "district": { "type": "keyword" }, | |
| "description": { "type": "text", "analyzer": "wedding_search" }, | |
| "priceRange": { | |
| "type": "nested", | |
| "properties": { | |
| "min": { "type": "double" }, | |
| "max": { "type": "double" } | |
| } | |
| }, | |
| "rating": { "type": "float" }, | |
| "reviewCount": { "type": "integer" }, | |
| "isVerified": { "type": "boolean" }, | |
| "isPublished": { "type": "boolean" }, | |
| "features": { "type": "keyword" }, | |
| "packages": { | |
| "type": "nested", | |
| "properties": { | |
| "id": { "type": "keyword" }, | |
| "name": { "type": "text" }, | |
| "price": { "type": "double" } | |
| } | |
| }, | |
| "availability": { | |
| "type": "nested", | |
| "properties": { | |
| "date": { "type": "date" }, | |
| "type": { "type": "keyword" } | |
| } | |
| }, | |
| "createdAt": { "type": "date" }, | |
| "updatedAt": { "type": "date" } | |
| } | |
| } | |
| } | |
| // Indexer Worker (BullMQ job) | |
| // On vendor create/update/publish, sync PostgreSQL -> OpenSearch: | |
| // | |
| // async function indexVendor(vendorId: string) { | |
| // const vendor = await db.vendorProfile.findUnique({ | |
| // where: { id: vendorId }, | |
| // include: { category: true, packages: true, availability: true } | |
| // }) | |
| // if (!vendor) return | |
| // await esClient.index({ | |
| // index: 'vendors', | |
| // id: vendor.id, | |
| // body: { | |
| // id: vendor.id, | |
| // businessName: vendor.businessName, | |
| // categoryId: vendor.categoryId, | |
| // categoryName: vendor.category.name, | |
| // district: vendor.district, | |
| // description: vendor.description, | |
| // priceRange: computePriceRange(vendor.packages), | |
| // rating: computeRating(vendor.id), | |
| // reviewCount: countReviews(vendor.id), | |
| // isVerified: vendor.isVerified, | |
| // isPublished: vendor.isPublished, | |
| // features: extractFeatures(vendor), | |
| // packages: vendor.packages.map(p => ({ id: p.id, name: p.name, price: Number(p.price) })), | |
| // availability: vendor.availability.map(a => ({ date: a.date, type: a.type })), | |
| // updatedAt: vendor.updatedAt, | |
| // } | |
| // }) | |
| // } | |
| // | |
| // // Faceted search example: | |
| // POST /vendors/_search | |
| // { | |
| // "query": { | |
| // "bool": { | |
| // "must": [ | |
| // { "term": { "isPublished": true } } | |
| // ], | |
| // "filter": [ | |
| // { "term": { "categoryName": "Photography" } }, | |
| // { "term": { "district": "Colombo 3" } }, | |
| // { "range": { "rating": { "gte": 4.5 } } } | |
| // ] | |
| // } | |
| // }, | |
| // "aggs": { | |
| // "by_category": { "terms": { "field": "categoryName" } }, | |
| // "by_district": { "terms": { "field": "district" } }, | |
| // "price_ranges": { | |
| // "range": { | |
| // "field": "rating", // placeholder - actual price range agg uses nested | |
| // "ranges": [ | |
| // { "key": "Under 50K", "to": 50000 }, | |
| // { "key": "50K-100K", "from": 50000, "to": 100000 }, | |
| // { "key": "100K-250K", "from": 100000, "to": 250000 }, | |
| // { "key": "250K-500K", "from": 250000, "to": 500000 }, | |
| // { "key": "Over 500K", "from": 500000 } | |
| // ] | |
| // } | |
| // } | |
| // }, | |
| // "sort": [{ "rating": "desc" }] | |
| // } | |