Blame view

api/result_formatter.py 5.89 KB
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
1
2
3
4
5
  """
  Result formatter for converting ES internal format to external-friendly format.
  """
  
  from typing import List, Dict, Any, Optional
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
6
  from .models import SpuResult, SkuResult, FacetResult, FacetValue
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
7
8
9
10
11
12
13
14
15
  
  
  class ResultFormatter:
      """Formats ES search results to external-friendly format."""
  
      @staticmethod
      def format_search_results(
          es_hits: List[Dict[str, Any]],
          max_score: float = 1.0
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
16
      ) -> List[SpuResult]:
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
17
          """
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
18
          Convert ES hits to SpuResult list.
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
19
20
21
  
          Args:
              es_hits: List of ES hit dictionaries (with _id, _score, _source)
f0577ce4   tangwang   fix last up
22
              max_score: Maximum score (unused, kept for compatibility)
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
23
24
  
          Returns:
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
25
              List of SpuResult objects
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
26
27
28
29
30
          """
          results = []
  
          for hit in es_hits:
              source = hit.get('_source', {})
cd3799c6   tangwang   tenant2 1w测试数据 mo...
31
              score = hit.get('_score')
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
32
              
f0577ce4   tangwang   fix last up
33
              # Use original ES score directly (no normalization)
cd3799c6   tangwang   tenant2 1w测试数据 mo...
34
35
36
37
38
39
40
41
              # Handle None score (can happen with certain query types or when score is explicitly null)
              if score is None:
                  relevance_score = 0.0
              else:
                  try:
                      relevance_score = float(score)
                  except (ValueError, TypeError):
                      relevance_score = 0.0
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
42
  
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
43
44
45
46
47
48
49
50
51
52
53
54
55
              # Extract SKUs
              skus = []
              skus_data = source.get('skus', [])
              if isinstance(skus_data, list):
                  for sku_entry in skus_data:
                      sku = SkuResult(
                          sku_id=str(sku_entry.get('sku_id', '')),
                          title=sku_entry.get('title'),
                          price=sku_entry.get('price'),
                          compare_at_price=sku_entry.get('compare_at_price'),
                          sku=sku_entry.get('sku'),
                          stock=sku_entry.get('stock', 0),
                          options=sku_entry.get('options')
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
56
                      )
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
57
                      skus.append(sku)
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
58
  
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
59
60
              # Determine in_stock (any sku has stock > 0)
              in_stock = any(sku.stock > 0 for sku in skus) if skus else True
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
61
  
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
62
63
64
              # Build SpuResult
              spu = SpuResult(
                  spu_id=str(source.get('spu_id', '')),
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
65
66
67
68
                  title=source.get('title'),
                  handle=source.get('handle'),
                  description=source.get('description'),
                  vendor=source.get('vendor'),
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
69
                  category=source.get('category'),
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
70
71
72
73
74
75
                  tags=source.get('tags'),
                  price=source.get('min_price'),
                  compare_at_price=source.get('compare_at_price'),
                  currency="USD",  # Default currency
                  image_url=source.get('image_url'),
                  in_stock=in_stock,
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
76
                  skus=skus,
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
77
78
79
                  relevance_score=relevance_score
              )
  
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
80
              results.append(spu)
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
  
          return results
  
      @staticmethod
      def format_facets(
          es_aggregations: Dict[str, Any],
          facet_configs: Optional[List[Any]] = None
      ) -> List[FacetResult]:
          """
          Format ES aggregations to FacetResult list.
  
          Args:
              es_aggregations: ES aggregations response
              facet_configs: Facet configurations (optional)
  
          Returns:
              List of FacetResult objects
          """
          facets = []
  
          for field_name, agg_data in es_aggregations.items():
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
102
              display_field = field_name[:-6] if field_name.endswith("_facet") else field_name
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
103
104
105
106
107
108
109
110
111
112
113
114
115
              # Handle terms aggregation
              if 'buckets' in agg_data:
                  values = []
                  for bucket in agg_data['buckets']:
                      value = FacetValue(
                          value=bucket['key'],
                          label=bucket.get('key_as_string', str(bucket['key'])),
                          count=bucket['doc_count'],
                          selected=False
                      )
                      values.append(value)
  
                  facet = FacetResult(
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
116
117
                      field=display_field,
                      label=display_field,  # Can be enhanced with field labels
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
                      type="terms",
                      values=values,
                      total_count=agg_data.get('sum_other_doc_count', 0) + len(values)
                  )
                  facets.append(facet)
  
              # Handle range aggregation
              elif 'buckets' in agg_data and any('from' in b or 'to' in b for b in agg_data['buckets']):
                  values = []
                  for bucket in agg_data['buckets']:
                      range_key = bucket.get('key', '')
                      value = FacetValue(
                          value=range_key,
                          label=range_key,
                          count=bucket['doc_count'],
                          selected=False
                      )
                      values.append(value)
  
                  facet = FacetResult(
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
138
139
                      field=display_field,
                      label=display_field,
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
140
141
142
143
144
145
146
147
148
149
                      type="range",
                      values=values
                  )
                  facets.append(facet)
  
          return facets
  
      @staticmethod
      def generate_suggestions(
          query: str,
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
150
          results: List[SpuResult]
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
      ) -> List[str]:
          """
          Generate search suggestions.
  
          Args:
              query: Original search query
              results: Search results
  
          Returns:
              List of suggestion strings (currently returns empty list)
          """
          # TODO: Implement suggestion generation logic
          return []
  
      @staticmethod
      def generate_related_searches(
          query: str,
cadc77b6   tangwang   索引字段名、变量名、API数据结构...
168
          results: List[SpuResult]
1f6d15fa   tangwang   重构:SPU级别索引、统一索引架构...
169
170
171
172
173
174
175
176
177
178
179
180
181
      ) -> List[str]:
          """
          Generate related searches.
  
          Args:
              query: Original search query
              results: Search results
  
          Returns:
              List of related search strings (currently returns empty list)
          """
          # TODO: Implement related search generation logic
          return []