# -*- coding: utf-8 -*- from pymongo import MongoClient from bson import ObjectId import sys import io import json # Fix encoding for Windows console if sys.platform == 'win32': sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') # MongoDB connection string MONGODB_URI = "mongodb://expenseuser:Kem_6o%3F%3F@165.227.69.221:27017/expense?authSource=admin" try: # Connect to MongoDB client = MongoClient(MONGODB_URI) db = client.expense # Test connection client.admin.command('ping') print("[OK] Successfully connected to MongoDB") print(f"Database: expense\n") # Find users with budgets that have category_id print("Searching for users with budgets that have category_id...") # Get user with most budgets user_with_most_budgets = "6741abd38d30ab5b7176397f" print(f"\nChecking user: {user_with_most_budgets} (has 243 budgets)") # Get budgets for this user user_budgets = list(db.budgets.find({ "$or": [ {"createdBy": ObjectId(user_with_most_budgets)}, {"createdBy": user_with_most_budgets}, {"user_id": ObjectId(user_with_most_budgets)}, {"user_id": user_with_most_budgets} ] }).limit(20)) print(f"Found {len(user_budgets)} budgets for this user\n") valid_combinations = [] for budget in user_budgets: created_by = str(budget.get("createdBy") or budget.get("user_id", "")) category_id = None # Try direct category fields category_id = budget.get("category") or budget.get("categoryId") or budget.get("headCategory") # Check headCategories array if not category_id: head_categories = budget.get("headCategories", []) if head_categories and isinstance(head_categories, list): for head_cat in head_categories: if isinstance(head_cat, dict): # Get headCategory ID head_cat_id = head_cat.get("headCategory") if head_cat_id: category_id = head_cat_id break # Get nested category IDs nested_cats = head_cat.get("categories", []) if nested_cats and isinstance(nested_cats, list): for nested_cat in nested_cats: if isinstance(nested_cat, dict): nested_cat_id = nested_cat.get("category") if nested_cat_id: category_id = nested_cat_id break if category_id: break if category_id: valid_combinations.append({ "user_id": created_by, "category_id": str(category_id), "budget_name": budget.get("name", "N/A"), "budget_id": str(budget.get("_id")) }) print(f"{'='*60}") print(f"Found {len(valid_combinations)} budgets with category_id") print(f"{'='*60}\n") if valid_combinations: print("[OK] User ID and Category ID combinations for testing:") print("-" * 60) seen = set() for i, combo in enumerate(valid_combinations[:10], 1): key = (combo["user_id"], combo["category_id"]) if key not in seen: seen.add(key) print(f"{i}. user_id: {combo['user_id']}") print(f" category_id: {combo['category_id']}") print(f" budget_name: {combo['budget_name']}") print() print(f"\n{'='*60}") print("[RECOMMENDED] Use this for testing:") print(f"{'='*60}") first = valid_combinations[0] print(f"user_id: {first['user_id']}") print(f"category_id: {first['category_id']}") print(f"{'='*60}\n") else: print("[WARNING] No budgets found with category_id") print("Checking sample budget structure...\n") # Show structure of first budget if user_budgets: sample = user_budgets[0] print("Sample budget structure:") print(f" _id: {sample.get('_id')}") print(f" createdBy: {sample.get('createdBy')}") print(f" user_id: {sample.get('user_id')}") print(f" name: {sample.get('name')}") print(f" category: {sample.get('category')}") print(f" categoryId: {sample.get('categoryId')}") print(f" headCategory: {sample.get('headCategory')}") print(f" has headCategories array: {bool(sample.get('headCategories'))}") if sample.get('headCategories'): print(f" headCategories length: {len(sample.get('headCategories', []))}") if len(sample.get('headCategories', [])) > 0: print(f" First headCategory structure:") print(json.dumps(sample.get('headCategories')[0], indent=2, default=str)) except Exception as e: print(f"[ERROR] Error: {e}") import traceback traceback.print_exc()