You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB与Mongoose合理Schema设计咨询:每日体重记录应用

Hey Anna, nice start with your user schema for the daily weight tracking app! As someone who’s worked with similar NoSQL schemas before, let’s go through some tweaks and best practices to make this more robust and scalable for your use case.

Key Observations & Quick Fixes

First, let’s polish your existing fields before diving into the weight record logic:

  • randomId field: You’ve marked it as unique: true but required: false—this is a bit conflicting. Since you already have a mandatory userId, that should be your primary unique identifier (I assume this comes from an auth system like your own login flow or a third-party tool). Unless you have a specific business need for a secondary numeric ID, this field is redundant and adds unnecessary index overhead—you can safely remove it.
  • hight typo: Small detail, but it should be height to avoid confusion down the line!
  • Age vs. Date of Birth: You mentioned users input age once, but age changes over time. Instead of storing a static age field, store dateOfBirth (as a Date type). You can always calculate the current age on the fly when displaying it to users, which avoids having to update the field every year.

Handling Daily Weight Records

This is the most critical part of your schema. You have two solid options depending on your future needs:

Option 1: Embed Weight Entries in the User Document

If you don’t expect users to log hundreds of thousands of weight entries (which is unlikely for a daily tracker), embedding records directly in the user document is efficient—you can fetch a user’s entire profile and weight history in a single query. Here’s how to adjust your schema:

const userSchema = new Schema({
  userId: { type: String, required: true, unique: true },
  name: String,
  dateOfBirth: { type: Date, required: true },
  height: { type: Number, required: true },
  gender: { type: String, enum: ['male', 'female', 'other'] }, // Enums enforce consistent data
  weightEntries: [
    {
      weight: { type: Number, required: true },
      recordDate: { type: Date, default: Date.now, index: true } // Index for fast date-based queries
    }
  ]
});

// Ensure userId is indexed for fast lookups
userSchema.index({ userId: 1 }, { unique: true });

Pros: Single query for user + weight data, low latency, simple to implement.
Cons: User documents will grow as entries are added (though MongoDB handles this well for reasonable sizes, like a few thousand entries per user).

Option 2: Separate Weight Records Into Their Own Collection

If you think you might add more metadata to weight entries later (like body fat percentage, notes, or workout links), or if you want to keep user documents lean, split the data into two collections. This is more flexible for long-term scaling:

// User Schema (core profile data)
const userSchema = new Schema({
  userId: { type: String, required: true, unique: true },
  name: String,
  dateOfBirth: { type: Date, required: true },
  height: { type: Number, required: true },
  gender: { type: String, enum: ['male', 'female', 'other'] }
});

// Weight Record Schema (linked to user via userId)
const weightRecordSchema = new Schema({
  userId: { type: String, required: true, ref: 'User' },
  weight: { type: Number, required: true },
  recordDate: { type: Date, default: Date.now }
});

// Compound index for fast queries like "get all weight records for user X sorted by date"
weightRecordSchema.index({ userId: 1, recordDate: -1 });

Pros: User documents stay small, weight records can be extended easily, and you can query records independently (e.g., generate trends across multiple users if needed).
Cons: You’ll need to use populate() (if using Mongoose) or join queries to fetch user data with their weight history, which adds a tiny bit of complexity but is standard practice.

Final Quick Tips

  • Always set required: true for fields that are mandatory (like height and dateOfBirth if users must input them once).
  • Use enums for fields with fixed options (like gender) to avoid invalid data entries.
  • Index fields you’ll query frequently—userId is a must, and recordDate if you’ll often filter or sort by date.

Hope this helps you build a solid foundation for your app! 😊

内容的提问来源于stack exchange,提问作者Anna K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:26:06