diff --git a/elastic/es_connect.py b/elastic/es_connect.py index 46c2575..0197433 100644 --- a/elastic/es_connect.py +++ b/elastic/es_connect.py @@ -5,6 +5,8 @@ Django版本的ES连接和操作模块 from elasticsearch import Elasticsearch from elasticsearch_dsl import connections import os +import json +import re from .documents import AchievementDocument, UserDocument, GlobalDocument from .indexes import ACHIEVEMENT_INDEX_NAME, USER_INDEX_NAME, GLOBAL_INDEX_NAME import hashlib @@ -321,23 +323,45 @@ def _compute_hist(range_gte: str, interval: str, fmt: str): buckets = getattr(resp.aggs, 'b').buckets return [{"label": b.key_as_string, "count": b.doc_count} for b in buckets] -def _compute_type_counts(range_gte: str, types: list): - counts = [] - for t in types: - s = AchievementDocument.search() - s = s.filter('range', time={'gte': range_gte, 'lte': 'now'}) - s = s.query('match_phrase', data=str(t)) - total = s.count() - counts.append({"type": str(t), "count": int(total)}) - return counts +def _parse_type_from_data(data_str: str): + try: + obj = json.loads(data_str) + if isinstance(obj, dict): + for k in ("数据类型", "类型", "type"): + if k in obj and obj.get(k): + return str(obj.get(k)).strip().strip(';') + except Exception: + pass + try: + m = re.search(r'"数据类型"\s*:\s*"(.*?)"', data_str) + if m: + return str(m.group(1)).strip().strip(';') + except Exception: + pass + return None + +def _compute_type_counts_dynamic(range_gte: str): + s = AchievementDocument.search() + s = s.filter('range', time={'gte': range_gte, 'lte': 'now'}) + s = s.query('match_all') + counts_map = {} + for hit in s.scan(): + t = _parse_type_from_data(getattr(hit, 'data', '') or '') + if not t: + continue + counts_map[t] = counts_map.get(t, 0) + 1 + try: + ensure_type_in_list(t) + except Exception: + pass + return [{"type": k, "count": int(v)} for k, v in counts_map.items()] def compute_analytics(): - types = get_type_list() days = _compute_hist('now-10d/d', 'day', 'yyyy-MM-dd') weeks = _compute_hist('now-10w/w', 'week', 'yyyy-ww') months = _compute_hist('now-10M/M', 'month', 'yyyy-MM') - pie_1m = _compute_type_counts('now-1M/M', types) - pie_12m = _compute_type_counts('now-12M/M', types) + pie_1m = _compute_type_counts_dynamic('now-1M/M') + pie_12m = _compute_type_counts_dynamic('now-12M/M') return { "last_10_days": days[-10:], "last_10_weeks": weeks[-10:],