如何在PyMongo中匹配两个城市书店统计实例列表?
Hey there! Let's figure out how to match your two PyMongo result lists effectively. From what you described, you want to find the corresponding travel bookstore stats for the 6 cities with the fewest total bookstores (your sixcities list) from your larger travelcities dataset. Here are a few straightforward approaches:
1. Match in Python (if you already have both lists loaded)
First, optimize the lookup by extracting city names from sixcities into a set—set lookups are O(1), way faster than list lookups for large datasets:
# Extract city names from sixcities into a set for fast lookup target_cities = {entry['_id'] for entry in sixcities} # Filter travelcities to only include entries from our target cities matched_results = [entry for entry in travelcities if entry['_id'] in target_cities]
If you need to combine the total bookstore count (from sixcities) with travel bookstore count (from travelcities) into a single structure, build a lookup dict first:
# Build a lookup dict for sixcities (city name -> total bookstore count) sixcities_lookup = {entry['_id']: entry['count'] for entry in sixcities} # Merge data from both lists into unified entries combined_results = [ { 'city': entry['_id'], 'total_bookstores': sixcities_lookup[entry['_id']], 'travel_bookstores': entry['count'] } for entry in travelcities if entry['_id'] in sixcities_lookup ]
2. Match Directly in MongoDB (more efficient if you haven't fetched travelcities yet)
Instead of pulling all 20+ cities' travel data into Python first, leverage MongoDB's indexing and querying to only return matching entries. This cuts down on data transfer and speeds up the process:
# First, get the list of city IDs from sixcities city_ids = [entry['_id'] for entry in sixcities] # Query the travel bookstore collection for only these cities matched_travel_data = list(db.your_travel_collection.find( {'_id': {'$in': city_ids}} )) # Combine with sixcities data using the lookup method above if needed
For an even cleaner workflow, combine the "find top 6 least bookstore cities" and "match travel data" steps into a single aggregation pipeline—no need for two separate queries:
pipeline = [ # Step 1: Aggregate to find the 6 cities with the fewest bookstores {'$group': {'_id': '$city', 'total_count': {'$sum': 1}}}, {'$sort': {'total_count': 1}}, # Ascending sort = fewest bookstores first {'$limit': 6}, # Step 2: Join with the travel bookstore stats collection {'$lookup': { 'from': 'your_travel_collection', # Name of your travel bookstore stats collection 'localField': '_id', 'foreignField': '_id', 'as': 'travel_stats' }}, # Flatten the travel_stats array for cleaner output {'$unwind': '$travel_stats'}, # Optional: Reshape the output to be more readable {'$project': { '_id': 0, 'city': '$_id', 'total_bookstores': '$total_count', 'travel_bookstores': '$travel_stats.count' }} ] # Run the pipeline to get combined results directly from the database final_results = list(db.your_main_bookstore_collection.aggregate(pipeline))
Which approach should you choose?
- Use Python-side matching if you already have both lists loaded in memory and just need a quick combination.
- Use MongoDB-side matching if you haven't fetched the travel data yet—it's far more efficient, especially as your dataset scales.
内容的提问来源于stack exchange,提问作者Will.S89

