Mongoose 查询:删除“_id”属性,在结果中保留虚拟属性 "id"
Mongoose query: remove "_id" attribute, keep virtual attribute "id" in results
我是 运行 一个 Express.js 应用程序,我有以下设置:
models.js
var schemaOptions = {
toJSON: {
virtuals: true
},
toObject: {
virtuals: true
}
};
var modelSchema = new mongoose.Schema({
name : { type: String, required: true }
}, schemaOptions);
modelSchema.virtual('id').get(function() { return this._id; });
controllers.js
exports.getModel = function(req, res) {
Model.find().select('name').exec(function(err,model) {
if (err) {
return res.status(500).json({errors:err, message: 'Internal server error'});
}
return res.status(200).json({model: model});
});
};
上述查询的结果类似于:
{ "_id":"dakjdjkakda", "name":"MontyPython", "id":"dakjdjkakda" }
因为我在modelSchema中定义了Virtual属性。
如果我将查询 select 语句更改为:
Model.find().select('-_id name').exec(function(err,model) {}
结果将是:
{"name":"MontyPython", "id":null }
我相信这是因为 Virtual 属性指向 _id 属性。
我的问题是,如何删除查询中的 _id 属性,但保留我创建的 id 别名?
你不能那样做。 MongoDB 要求根据 documentation.
存在 _id
属性
您的选择是像示例中那样使用虚拟属性,也许 $project 隐藏查询结果中的字段。
否则,您的 mongo 驱动程序(例如 Mongoose)应该能够隐藏或重命名所需的字段或属性。
如果您使用猫鼬,
你可以在何时处理toJSON,你可以决定它如何显示,但你不能在你的查询中提及它。
Model.find().select('name').exec(function(err,model) {}
new mongoose.Schema(yourSchema, {
toJSON: {
transform: function(doc, ret) {
ret.id = ret._id;
delete ret._id;
}
}
);}
您可以使用全局方法。试试这个:
mongoose.plugin((schema) => {
schema.options.toJSON = {
virtuals: true,
versionKey: false,
transform(doc, ret) {
ret.id = ret._id;
delete ret._id;
}
};
});
这是我在 lodash 的帮助下完成的方法:)
请注意,您可以通过设置隐藏选项隐藏任何您想要的字段
customerSchema.set('toObject', {
hide: '_id version passcodeHash',
transform: (doc, ret, options) => _.omit(ret, options.hide.split(' ')),
})
您可以像这样添加虚拟字段 id
,因为您在代码中做对了:
modelSchema.virtual('id').get(function () {
return this._id;
});
然后使用 toJSON
的转换选项删除实际的 _id
:
modelSchema.set('toJSON', {
virtuals: true,
transform: function(doc, ret) {
delete ret._id;
}
});
设置 virtuals: true
将确保您的虚拟字段,即 id
将被序列化。
我是 运行 一个 Express.js 应用程序,我有以下设置:
models.js
var schemaOptions = {
toJSON: {
virtuals: true
},
toObject: {
virtuals: true
}
};
var modelSchema = new mongoose.Schema({
name : { type: String, required: true }
}, schemaOptions);
modelSchema.virtual('id').get(function() { return this._id; });
controllers.js
exports.getModel = function(req, res) {
Model.find().select('name').exec(function(err,model) {
if (err) {
return res.status(500).json({errors:err, message: 'Internal server error'});
}
return res.status(200).json({model: model});
});
};
上述查询的结果类似于:
{ "_id":"dakjdjkakda", "name":"MontyPython", "id":"dakjdjkakda" }
因为我在modelSchema中定义了Virtual属性。
如果我将查询 select 语句更改为:
Model.find().select('-_id name').exec(function(err,model) {}
结果将是:
{"name":"MontyPython", "id":null }
我相信这是因为 Virtual 属性指向 _id 属性。
我的问题是,如何删除查询中的 _id 属性,但保留我创建的 id 别名?
你不能那样做。 MongoDB 要求根据 documentation.
存在_id
属性
您的选择是像示例中那样使用虚拟属性,也许 $project 隐藏查询结果中的字段。
否则,您的 mongo 驱动程序(例如 Mongoose)应该能够隐藏或重命名所需的字段或属性。
如果您使用猫鼬,
你可以在何时处理toJSON,你可以决定它如何显示,但你不能在你的查询中提及它。
Model.find().select('name').exec(function(err,model) {}
new mongoose.Schema(yourSchema, {
toJSON: {
transform: function(doc, ret) {
ret.id = ret._id;
delete ret._id;
}
}
);}
您可以使用全局方法。试试这个:
mongoose.plugin((schema) => {
schema.options.toJSON = {
virtuals: true,
versionKey: false,
transform(doc, ret) {
ret.id = ret._id;
delete ret._id;
}
};
});
这是我在 lodash 的帮助下完成的方法:)
请注意,您可以通过设置隐藏选项隐藏任何您想要的字段
customerSchema.set('toObject', {
hide: '_id version passcodeHash',
transform: (doc, ret, options) => _.omit(ret, options.hide.split(' ')),
})
您可以像这样添加虚拟字段 id
,因为您在代码中做对了:
modelSchema.virtual('id').get(function () {
return this._id;
});
然后使用 toJSON
的转换选项删除实际的 _id
:
modelSchema.set('toJSON', {
virtuals: true,
transform: function(doc, ret) {
delete ret._id;
}
});
设置 virtuals: true
将确保您的虚拟字段,即 id
将被序列化。