Commit
·
751a827
1
Parent(s):
0254ce4
修正進階查詢
Browse files- backend/services/enhanced_product_service.py +20 -14
- test_emergency_fix.py +214 -0
backend/services/enhanced_product_service.py
CHANGED
@@ -298,11 +298,19 @@ class EnhancedProductService:
|
|
298 |
def _extract_keywords(self, query_text: str) -> List[str]:
|
299 |
"""從查詢文字中提取關鍵字,並擴展相關詞彙"""
|
300 |
# 移除常見的查詢詞彙
|
301 |
-
stop_words = ['推薦', '有沒有', '是否有', '請問', '想要', '需要', '找', '查詢', '搜尋', '還有嗎', '還有', '嗎']
|
302 |
|
303 |
# 清理查詢文字
|
304 |
cleaned_text = query_text.replace('?', '').replace('?', '').strip()
|
305 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
306 |
# 分割並清理關鍵字
|
307 |
words = cleaned_text.split()
|
308 |
keywords = []
|
@@ -311,22 +319,16 @@ class EnhancedProductService:
|
|
311 |
if word not in stop_words and len(word) > 1:
|
312 |
keywords.append(word)
|
313 |
|
314 |
-
#
|
315 |
-
|
316 |
-
# 嘗試提取核心商品詞彙
|
317 |
-
core_words = ['貓砂', '狗糧', '寵物', '商品', '產品']
|
318 |
-
for core_word in core_words:
|
319 |
-
if core_word in cleaned_text:
|
320 |
-
keywords.append(core_word)
|
321 |
-
break
|
322 |
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
|
327 |
# 擴展相關關鍵字
|
328 |
expanded_keywords = []
|
329 |
-
for keyword in
|
330 |
expanded_keywords.append(keyword)
|
331 |
|
332 |
# 貓砂相關擴展
|
@@ -341,10 +343,14 @@ class EnhancedProductService:
|
|
341 |
if '寵物' in keyword:
|
342 |
expanded_keywords.extend(['貓', '狗', '犬', 'pet', 'cat'])
|
343 |
|
|
|
|
|
|
|
|
|
344 |
# 去除重複並返回
|
345 |
unique_keywords = list(set(expanded_keywords))
|
346 |
|
347 |
# 記錄關鍵字提取結果用於調試
|
348 |
-
logger.info(f"關鍵字提取: '{query_text}' → {unique_keywords}")
|
349 |
|
350 |
return unique_keywords
|
|
|
298 |
def _extract_keywords(self, query_text: str) -> List[str]:
|
299 |
"""從查詢文字中提取關鍵字,並擴展相關詞彙"""
|
300 |
# 移除常見的查詢詞彙
|
301 |
+
stop_words = ['推薦', '有沒有', '是否有', '請問', '想要', '需要', '找', '查詢', '搜尋', '還有嗎', '還有', '嗎', '可以']
|
302 |
|
303 |
# 清理查詢文字
|
304 |
cleaned_text = query_text.replace('?', '').replace('?', '').strip()
|
305 |
|
306 |
+
# 先嘗試提取核心商品詞彙
|
307 |
+
core_product_words = ['貓砂', '狗糧', '寵物', '商品', '產品', '貓', '狗', '犬', '礦砂']
|
308 |
+
extracted_core_words = []
|
309 |
+
|
310 |
+
for core_word in core_product_words:
|
311 |
+
if core_word in cleaned_text:
|
312 |
+
extracted_core_words.append(core_word)
|
313 |
+
|
314 |
# 分割並清理關鍵字
|
315 |
words = cleaned_text.split()
|
316 |
keywords = []
|
|
|
319 |
if word not in stop_words and len(word) > 1:
|
320 |
keywords.append(word)
|
321 |
|
322 |
+
# 合併核心詞彙和分割的關鍵字
|
323 |
+
all_keywords = list(set(extracted_core_words + keywords))
|
|
|
|
|
|
|
|
|
|
|
|
|
324 |
|
325 |
+
# 如果沒有有效關鍵字,使用清理後的文字
|
326 |
+
if not all_keywords:
|
327 |
+
all_keywords = [cleaned_text]
|
328 |
|
329 |
# 擴展相關關鍵字
|
330 |
expanded_keywords = []
|
331 |
+
for keyword in all_keywords:
|
332 |
expanded_keywords.append(keyword)
|
333 |
|
334 |
# 貓砂相關擴展
|
|
|
343 |
if '寵物' in keyword:
|
344 |
expanded_keywords.extend(['貓', '狗', '犬', 'pet', 'cat'])
|
345 |
|
346 |
+
# 商品相關擴展
|
347 |
+
if '商品' in keyword or '產品' in keyword:
|
348 |
+
expanded_keywords.extend(['貓砂', '狗糧', '寵物', '食品', '用品'])
|
349 |
+
|
350 |
# 去除重複並返回
|
351 |
unique_keywords = list(set(expanded_keywords))
|
352 |
|
353 |
# 記錄關鍵字提取結果用於調試
|
354 |
+
logger.info(f"關鍵字提取: '{query_text}' → 核心詞: {extracted_core_words} → 最終: {unique_keywords}")
|
355 |
|
356 |
return unique_keywords
|
test_emergency_fix.py
ADDED
@@ -0,0 +1,214 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
緊急測試修復後的關鍵字提取
|
3 |
+
"""
|
4 |
+
|
5 |
+
def test_emergency_keyword_extraction():
|
6 |
+
"""測試緊急修復的關鍵字提取"""
|
7 |
+
|
8 |
+
def extract_keywords_emergency(query_text: str):
|
9 |
+
"""緊急修復版的關鍵字提取邏輯"""
|
10 |
+
# 移除常見的查詢詞彙
|
11 |
+
stop_words = ['推薦', '有沒有', '是否有', '請問', '想要', '需要', '找', '查詢', '搜尋', '還有嗎', '還有', '嗎', '可以']
|
12 |
+
|
13 |
+
# 清理查詢文字
|
14 |
+
cleaned_text = query_text.replace('?', '').replace('?', '').strip()
|
15 |
+
|
16 |
+
# 先嘗試提取核心商品詞彙
|
17 |
+
core_product_words = ['貓砂', '狗糧', '寵物', '商品', '產品', '貓', '狗', '犬', '礦砂']
|
18 |
+
extracted_core_words = []
|
19 |
+
|
20 |
+
for core_word in core_product_words:
|
21 |
+
if core_word in cleaned_text:
|
22 |
+
extracted_core_words.append(core_word)
|
23 |
+
|
24 |
+
# 分割並清理關鍵字
|
25 |
+
words = cleaned_text.split()
|
26 |
+
keywords = []
|
27 |
+
|
28 |
+
for word in words:
|
29 |
+
if word not in stop_words and len(word) > 1:
|
30 |
+
keywords.append(word)
|
31 |
+
|
32 |
+
# 合併核心詞彙和分割的關鍵字
|
33 |
+
all_keywords = list(set(extracted_core_words + keywords))
|
34 |
+
|
35 |
+
# 如果沒有有效關鍵字,使用清理後的文字
|
36 |
+
if not all_keywords:
|
37 |
+
all_keywords = [cleaned_text]
|
38 |
+
|
39 |
+
# 擴展相關關鍵字
|
40 |
+
expanded_keywords = []
|
41 |
+
for keyword in all_keywords:
|
42 |
+
expanded_keywords.append(keyword)
|
43 |
+
|
44 |
+
# 貓砂相關擴展
|
45 |
+
if '貓砂' in keyword or '貓' in keyword:
|
46 |
+
expanded_keywords.extend(['礦砂', '豆腐砂', '水晶砂', '木屑砂', 'litter', '貓砂'])
|
47 |
+
|
48 |
+
# 狗糧相關擴展
|
49 |
+
if '狗糧' in keyword or '狗' in keyword:
|
50 |
+
expanded_keywords.extend(['犬糧', '犬種', '狗食', 'dog'])
|
51 |
+
|
52 |
+
# 寵物相關擴展
|
53 |
+
if '寵物' in keyword:
|
54 |
+
expanded_keywords.extend(['貓', '狗', '犬', 'pet', 'cat'])
|
55 |
+
|
56 |
+
# 商品相關擴展
|
57 |
+
if '商品' in keyword or '產品' in keyword:
|
58 |
+
expanded_keywords.extend(['貓砂', '狗糧', '寵物', '食品', '用品'])
|
59 |
+
|
60 |
+
# 去除重複並返回
|
61 |
+
unique_keywords = list(set(expanded_keywords))
|
62 |
+
|
63 |
+
return unique_keywords, extracted_core_words
|
64 |
+
|
65 |
+
print("🚨 緊急測試關鍵字提取修復")
|
66 |
+
print("=" * 50)
|
67 |
+
|
68 |
+
# 測試實際的用戶查詢
|
69 |
+
test_cases = [
|
70 |
+
"請問有商品可以推薦嗎?",
|
71 |
+
"請問貓砂還有嗎?",
|
72 |
+
"貓砂還有嗎?",
|
73 |
+
"推薦一些商品",
|
74 |
+
"有什麼寵物用品?"
|
75 |
+
]
|
76 |
+
|
77 |
+
for query in test_cases:
|
78 |
+
print(f"\n查詢: '{query}'")
|
79 |
+
keywords, core_words = extract_keywords_emergency(query)
|
80 |
+
print(f" 核心詞彙: {core_words}")
|
81 |
+
print(f" 最終關鍵字: {keywords}")
|
82 |
+
|
83 |
+
# 檢查是否包含預期的關鍵字
|
84 |
+
if "貓砂" in query:
|
85 |
+
if '貓砂' in keywords and '礦砂' in keywords:
|
86 |
+
print(" ✅ 包含預期的貓砂相關關鍵字")
|
87 |
+
else:
|
88 |
+
print(" ❌ 缺少預期的貓砂關鍵字")
|
89 |
+
|
90 |
+
if "商品" in query:
|
91 |
+
if any(word in keywords for word in ['商品', '貓砂', '狗糧', '寵物']):
|
92 |
+
print(" ✅ 包含商品相關關鍵字")
|
93 |
+
else:
|
94 |
+
print(" ❌ 缺少商品相關關鍵字")
|
95 |
+
|
96 |
+
def test_product_matching_emergency():
|
97 |
+
"""測試緊急修復的商品匹配"""
|
98 |
+
|
99 |
+
def extract_keywords_emergency(query_text: str):
|
100 |
+
stop_words = ['推薦', '有沒有', '是否有', '請問', '想要', '需要', '找', '查詢', '搜尋', '還有嗎', '還有', '嗎', '可以']
|
101 |
+
cleaned_text = query_text.replace('?', '').replace('?', '').strip()
|
102 |
+
|
103 |
+
core_product_words = ['貓砂', '狗糧', '寵物', '商品', '產品', '貓', '狗', '犬', '礦砂']
|
104 |
+
extracted_core_words = []
|
105 |
+
|
106 |
+
for core_word in core_product_words:
|
107 |
+
if core_word in cleaned_text:
|
108 |
+
extracted_core_words.append(core_word)
|
109 |
+
|
110 |
+
words = cleaned_text.split()
|
111 |
+
keywords = [word for word in words if word not in stop_words and len(word) > 1]
|
112 |
+
|
113 |
+
all_keywords = list(set(extracted_core_words + keywords))
|
114 |
+
|
115 |
+
if not all_keywords:
|
116 |
+
all_keywords = [cleaned_text]
|
117 |
+
|
118 |
+
expanded_keywords = []
|
119 |
+
for keyword in all_keywords:
|
120 |
+
expanded_keywords.append(keyword)
|
121 |
+
|
122 |
+
if '貓砂' in keyword or '貓' in keyword:
|
123 |
+
expanded_keywords.extend(['礦砂', '豆腐砂', '水晶砂', '木屑砂', 'litter', '貓砂'])
|
124 |
+
|
125 |
+
if '狗糧' in keyword or '狗' in keyword:
|
126 |
+
expanded_keywords.extend(['犬糧', '犬種', '狗食', 'dog'])
|
127 |
+
|
128 |
+
if '寵物' in keyword:
|
129 |
+
expanded_keywords.extend(['貓', '狗', '犬', 'pet', 'cat'])
|
130 |
+
|
131 |
+
if '商品' in keyword or '產品' in keyword:
|
132 |
+
expanded_keywords.extend(['貓砂', '狗糧', '寵物', '食品', '用品'])
|
133 |
+
|
134 |
+
return list(set(expanded_keywords))
|
135 |
+
|
136 |
+
# 實際商品資料
|
137 |
+
products = [
|
138 |
+
{
|
139 |
+
"id": 1,
|
140 |
+
"productCode": "OL1100-1",
|
141 |
+
"productName": "毆力天然犬種300g 室內成犬無榖小顆粒",
|
142 |
+
"stock": 100
|
143 |
+
},
|
144 |
+
{
|
145 |
+
"id": 2,
|
146 |
+
"productCode": "SW-06-01",
|
147 |
+
"productName": "Shovel well豪好鏟 破碎型礦砂",
|
148 |
+
"stock": 50
|
149 |
+
},
|
150 |
+
{
|
151 |
+
"id": 3,
|
152 |
+
"productCode": "TL-03",
|
153 |
+
"productName": "美國極冠貓砂 薰衣草12kg",
|
154 |
+
"stock": 48
|
155 |
+
},
|
156 |
+
{
|
157 |
+
"id": 4,
|
158 |
+
"productCode": "SL11002",
|
159 |
+
"productName": "首領汪 膠原鴨舌 5入彭湃包",
|
160 |
+
"stock": 100
|
161 |
+
}
|
162 |
+
]
|
163 |
+
|
164 |
+
print("\n🛍️ 緊急測試商品匹配")
|
165 |
+
print("=" * 50)
|
166 |
+
|
167 |
+
test_queries = [
|
168 |
+
"請問有商品可以推薦嗎?",
|
169 |
+
"請問貓砂還有嗎?",
|
170 |
+
"貓砂還有嗎?"
|
171 |
+
]
|
172 |
+
|
173 |
+
for query in test_queries:
|
174 |
+
print(f"\n查詢: '{query}'")
|
175 |
+
keywords = extract_keywords_emergency(query)
|
176 |
+
print(f"關鍵字: {keywords}")
|
177 |
+
|
178 |
+
matched_products = []
|
179 |
+
|
180 |
+
for product in products:
|
181 |
+
product_name_lower = product["productName"].lower()
|
182 |
+
product_code_lower = product["productCode"].lower()
|
183 |
+
|
184 |
+
for keyword in keywords:
|
185 |
+
keyword_lower = keyword.lower()
|
186 |
+
|
187 |
+
if (keyword_lower in product_name_lower or
|
188 |
+
keyword_lower in product_code_lower):
|
189 |
+
if product not in matched_products:
|
190 |
+
matched_products.append(product)
|
191 |
+
print(f" ✅ 匹配: {product['productName']} (關鍵字: {keyword})")
|
192 |
+
break
|
193 |
+
|
194 |
+
print(f"找到 {len(matched_products)} 個商品")
|
195 |
+
|
196 |
+
if not matched_products:
|
197 |
+
print(" ❌ 沒有找到商品 - 需要進一步調試")
|
198 |
+
|
199 |
+
def main():
|
200 |
+
"""主函數"""
|
201 |
+
print("🚨 緊急修復測試")
|
202 |
+
print("=" * 60)
|
203 |
+
|
204 |
+
test_emergency_keyword_extraction()
|
205 |
+
test_product_matching_emergency()
|
206 |
+
|
207 |
+
print("\n" + "=" * 60)
|
208 |
+
print("🔍 診斷結果:")
|
209 |
+
print("1. 檢查關鍵字提取是否正確")
|
210 |
+
print("2. 檢查商品匹配邏輯")
|
211 |
+
print("3. 如果測試通過,重啟服務應該能工作")
|
212 |
+
|
213 |
+
if __name__ == "__main__":
|
214 |
+
main()
|