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

Mongoose查询时获取关联对象而非ID,Populate失效求助

Mongoose Populate Not Working for Transaction-Borne Association & Getter Issues

Let's break down your problems one by one and fix them step by step.

First: Fixing the Populate Failure

The most common reason populate() doesn't work is a mismatch between the ref value in your schema and the actual model name you registered with Mongoose. Let's start there:

1. Match ref to Your Model Registration

Looking at your code:

  • In your Transaction schema, you have _borne: { type: Schema.Types.ObjectId, ref: 'Borne' } (capitalized singular)
  • But in your routes, you're loading the model as mongoose.model('bornes') (lowercase plural)

Mongoose uses the exact string from ref to look up the model. You have two fix options:

Option A: Update the Transaction schema's ref

If your Borne model is registered as mongoose.model('bornes', borneSchema), adjust the ref to match:

_borne: { type: Schema.Types.ObjectId, ref: 'bornes' },

Option B: Update the Borne model registration

If you prefer using a singular capitalized name, register the Borne model like this:

mongoose.model('Borne', borneSchema); // instead of 'bornes'

Then keep ref: 'Borne' in the Transaction schema.

2. Simplify ObjectID Handling

You don't need to manually convert strings to ObjectID—Mongoose handles this automatically. Clean up your query code:

const transactions = await Transaction.find({
  _user: id, // Mongoose converts string IDs to ObjectID automatically
  status: { $nin: ['booked', 'charging', 'charged', 'left'] }
})
.populate('_user')
.populate('_borne')
.sort({ updatedAt: -1 });

3. Verify Database Data

Double-check two critical things in MongoDB:

  • Ensure your Transaction documents have valid _borne ObjectIDs that actually exist in the bornes (or Borne) collection
  • Confirm there are Transaction documents that match your status filter—an empty result set might make you think populate isn't working, even if it's functioning correctly

Second: Fixing the Getter Not Taking Effect

Mongoose doesn't apply getters to query results by default when serializing to JSON. You need to enable this in your schema options:

Update Your Transaction Schema

Add toJSON/toObject settings to activate getters, plus use timestamps to auto-manage createdAt/updatedAt (saves you from setting them manually):

const transactionSchema = new Schema({
  status: String,
  details: {
    amount: { type: Number },
    quantity: { type: Number },
    date: { type: Date },
    city: { type: String }
  },
  logs: [
    { state: String, date: Date }
  ],
  _user: { type: Schema.Types.ObjectId, ref: 'bornes' }, // Match your model name
  _borne: { type: Schema.Types.ObjectId, ref: 'bornes' }, // Match your model name
  createdAt: Date,
  updatedAt: Date
}, {
  timestamps: true, // Auto-sets createdAt/updatedAt on create/save
  toJSON: { getters: true }, // Apply getters when converting to JSON
  toObject: { getters: true } // Apply getters when converting to plain object
});

// Now your status getter will work as expected
transactionSchema.path('status').get(function(value) {
  return `Custom status: ${value}`; // Replace with your desired logic
});

mongoose.model('transactions', transactionSchema);

Final Checks

After making these changes:

  1. Restart your server to apply schema updates
  2. Test your /v1/user/:id/transactions endpoint again—you should see full Borne objects in the response
  3. The status field should now show your modified value from the getter

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:57:27