请求MongoDB存储Google Place API数据(用户&位置级)的结构建议
Great question! MongoDB’s flexible document model is perfect for this use case—let’s build a schema that balances data integrity, query performance, and support for both user-specific tracking and location data management. Below is a structured approach with core collections, key fields, and best practices.
Core Collections to Implement
1. users Collection
Stores basic user profile data and optional preferences. Keep this lean unless you need additional user attributes:
_id: MongoDB’s default ObjectId (primary key)externalUserId: (Optional) Your app’s unique user identifier (if integrating with an existing auth system)email: (Optional) User’s email for account-related actionspreferences: (Optional) Nested document for user preferences, e.g.,{ defaultSearchRadius: 5000, favoriteCategories: ["restaurant", "park"] }createdAt: Timestamp of user account creationupdatedAt: Timestamp of last profile update
2. places Collection
Stores normalized Google Place API data—this is your single source of truth for location details. Prioritize fields you’ll query frequently, and keep the full API response as a fallback:
_id: MongoDB ObjectIdplaceId: Required Google’s official Place ID (add a unique index here to avoid duplicate entries)name: Place name (e.g., "Central Park")formattedAddress: Full address from Google’sformatted_addressfieldlocation: GeoJSON Point for geospatial queries, e.g.,{ type: "Point", coordinates: [-73.9712, 40.7831] }types: Array of place categories (e.g.,["park", "tourist_attraction"])rating: Google’s user rating (0-5)userRatingsTotal: Total number of ratings for the placegoogleRawData: (Optional) Nested document storing the full Google Place API response—useful if you need to access less-frequent fields later without re-calling the APIlastSyncedAt: Timestamp of the last time you refreshed data from Google Place API (for periodic updates)createdAt: Timestamp when the place was first storedupdatedAt: Timestamp of last data update
Example places document:
{ "_id": ObjectId("60d21b4667d0d8992e610c85"), "placeId": "ChIJN1t_tDeuEmsRUsoyG83frY4", "name": "Central Park", "formattedAddress": "New York, NY 10022, USA", "location": { "type": "Point", "coordinates": [-73.9712, 40.7831] }, "types": ["park", "tourist_attraction"], "rating": 4.8, "userRatingsTotal": 123456, "googleRawData": { "formatted_phone_number": "(212) 310-6600", "website": "https://www.centralparknyc.org/", "opening_hours": { "open_now": true } // Include other API fields as needed }, "lastSyncedAt": ISODate("2024-05-20T14:30:00Z"), "createdAt": ISODate("2024-05-15T09:15:00Z"), "updatedAt": ISODate("2024-05-20T14:30:00Z") }
3. userSearchHistory Collection
Tracks user-specific search activity to enable retrieval and behavioral analysis. This collection links users to places (or raw search queries) with context:
_id: MongoDB ObjectIduserId: Reference tousers._idorusers.externalUserId(use a consistent key)placeId: (Optional) Reference toplaces.placeId—only if the search resulted in a specific place matchsearchQuery: Required The exact search term the user entered (e.g., "best coffee in Brooklyn")searchTimestamp: Timestamp when the search was performed (critical for time-based retrieval)searchFilters: (Optional) Nested document of filters applied, e.g.,{ radius: 5000, type: "restaurant", openNow: true }resultsCount: Number of places returned in the searchselectedPlaceId: (Optional) If the user clicked/selected a specific place from results, store itsplaceId(great for preference analysis)createdAt: Timestamp when the search record was saved
Example userSearchHistory document:
{ "_id": ObjectId("60d21b8967d0d8992e610c86"), "userId": "user_12345", "placeId": "ChIJN1t_tDeuEmsRUsoyG83frY4", "searchQuery": "central park nyc", "searchTimestamp": ISODate("2024-05-20T15:45:00Z"), "searchFilters": { "radius": 1000, "type": "park" }, "resultsCount": 5, "selectedPlaceId": "ChIJN1t_tDeuEmsRUsoyG83frY4", "createdAt": ISODate("2024-05-20T15:45:00Z") }
Key Indexes for Performance
To ensure fast queries, add these indexes:
users: Single-key index onexternalUserId(if used) for quick user lookupsplaces:- Unique index on
placeIdto prevent duplicates - 2dsphere index on
locationfor geospatial queries (e.g., "find places within 5km of a point") - Multi-key index on
typesfor category-based filtering
- Unique index on
userSearchHistory:- Compound index on
userId+searchTimestampto quickly fetch a user’s recent search history - Compound index on
userId+placeIdto analyze which places a user frequently searches for
- Compound index on
Optional Additions (Based on Your Needs)
userFavorites: A separate collection if you want to track user-saved places (better for scalability than embedding an array inusersif users save many places)placeReviews: If you want to store user-generated reviews for places (link touserIdandplaceId)
内容的提问来源于stack exchange,提问作者Faisal Khan

