imeshuek commited on
Commit
abe028d
·
verified ·
1 Parent(s): 0939458

Upload api/search/opensearch-mapping.json

Browse files
Files changed (1) hide show
  1. api/search/opensearch-mapping.json +124 -0
api/search/opensearch-mapping.json ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // OpenSearch Index Mapping for Vendor Search
2
+ // Supports faceted search: category, district, price range, rating, and full-text
3
+
4
+ PUT /vendors
5
+ {
6
+ "settings": {
7
+ "number_of_shards": 2,
8
+ "number_of_replicas": 1,
9
+ "analysis": {
10
+ "analyzer": {
11
+ "wedding_search": {
12
+ "type": "custom",
13
+ "tokenizer": "standard",
14
+ "filter": ["lowercase", "asciifolding", "stop", "snowball"]
15
+ }
16
+ }
17
+ }
18
+ },
19
+ "mappings": {
20
+ "properties": {
21
+ "id": { "type": "keyword" },
22
+ "businessName": { "type": "text", "analyzer": "wedding_search", "fields": { "keyword": { "type": "keyword" } } },
23
+ "categoryId": { "type": "keyword" },
24
+ "categoryName": { "type": "keyword" },
25
+ "district": { "type": "keyword" },
26
+ "description": { "type": "text", "analyzer": "wedding_search" },
27
+ "priceRange": {
28
+ "type": "nested",
29
+ "properties": {
30
+ "min": { "type": "double" },
31
+ "max": { "type": "double" }
32
+ }
33
+ },
34
+ "rating": { "type": "float" },
35
+ "reviewCount": { "type": "integer" },
36
+ "isVerified": { "type": "boolean" },
37
+ "isPublished": { "type": "boolean" },
38
+ "features": { "type": "keyword" },
39
+ "packages": {
40
+ "type": "nested",
41
+ "properties": {
42
+ "id": { "type": "keyword" },
43
+ "name": { "type": "text" },
44
+ "price": { "type": "double" }
45
+ }
46
+ },
47
+ "availability": {
48
+ "type": "nested",
49
+ "properties": {
50
+ "date": { "type": "date" },
51
+ "type": { "type": "keyword" }
52
+ }
53
+ },
54
+ "createdAt": { "type": "date" },
55
+ "updatedAt": { "type": "date" }
56
+ }
57
+ }
58
+ }
59
+
60
+ // Indexer Worker (BullMQ job)
61
+ // On vendor create/update/publish, sync PostgreSQL -> OpenSearch:
62
+ //
63
+ // async function indexVendor(vendorId: string) {
64
+ // const vendor = await db.vendorProfile.findUnique({
65
+ // where: { id: vendorId },
66
+ // include: { category: true, packages: true, availability: true }
67
+ // })
68
+ // if (!vendor) return
69
+ // await esClient.index({
70
+ // index: 'vendors',
71
+ // id: vendor.id,
72
+ // body: {
73
+ // id: vendor.id,
74
+ // businessName: vendor.businessName,
75
+ // categoryId: vendor.categoryId,
76
+ // categoryName: vendor.category.name,
77
+ // district: vendor.district,
78
+ // description: vendor.description,
79
+ // priceRange: computePriceRange(vendor.packages),
80
+ // rating: computeRating(vendor.id),
81
+ // reviewCount: countReviews(vendor.id),
82
+ // isVerified: vendor.isVerified,
83
+ // isPublished: vendor.isPublished,
84
+ // features: extractFeatures(vendor),
85
+ // packages: vendor.packages.map(p => ({ id: p.id, name: p.name, price: Number(p.price) })),
86
+ // availability: vendor.availability.map(a => ({ date: a.date, type: a.type })),
87
+ // updatedAt: vendor.updatedAt,
88
+ // }
89
+ // })
90
+ // }
91
+ //
92
+ // // Faceted search example:
93
+ // POST /vendors/_search
94
+ // {
95
+ // "query": {
96
+ // "bool": {
97
+ // "must": [
98
+ // { "term": { "isPublished": true } }
99
+ // ],
100
+ // "filter": [
101
+ // { "term": { "categoryName": "Photography" } },
102
+ // { "term": { "district": "Colombo 3" } },
103
+ // { "range": { "rating": { "gte": 4.5 } } }
104
+ // ]
105
+ // }
106
+ // },
107
+ // "aggs": {
108
+ // "by_category": { "terms": { "field": "categoryName" } },
109
+ // "by_district": { "terms": { "field": "district" } },
110
+ // "price_ranges": {
111
+ // "range": {
112
+ // "field": "rating", // placeholder - actual price range agg uses nested
113
+ // "ranges": [
114
+ // { "key": "Under 50K", "to": 50000 },
115
+ // { "key": "50K-100K", "from": 50000, "to": 100000 },
116
+ // { "key": "100K-250K", "from": 100000, "to": 250000 },
117
+ // { "key": "250K-500K", "from": 250000, "to": 500000 },
118
+ // { "key": "Over 500K", "from": 500000 }
119
+ // ]
120
+ // }
121
+ // }
122
+ // },
123
+ // "sort": [{ "rating": "desc" }]
124
+ // }