Я использую мангуст (узел), как лучше всего вывести идентификатор вместо _id?
MongoDB: вывод «id» вместо «_id»
Ответы (16)
Я создаю метод toClient() в своих моделях, где я это делаю. Это также хорошее место для переименования/удаления других атрибутов, которые вы не хотите отправлять клиенту:
Schema.method('toClient', function() {
var obj = this.toObject();
//Rename fields
obj.id = obj._id;
delete obj._id;
return obj;
});
Учитывая, что вы используете Mongoose, вы можете использовать «виртуальные», которые по сути являются фальшивыми полями, которые создает Mongoose. Они не хранятся в БД, они просто заполняются во время выполнения:
// Duplicate the ID field.
Schema.virtual('id').get(function(){
return this._id.toHexString();
});
// Ensure virtual fields are serialised.
Schema.set('toJSON', {
virtuals: true
});
Каждый раз, когда toJSON вызывается для модели, которую вы создаете из этой схемы, она будет включать поле «id», которое соответствует полю _id, которое генерирует Mongo. Точно так же вы можете установить поведение для toObject таким же образом.
Видеть:
- http://mongoosejs.com/docs/api.html
- http://mongoosejs.com/docs/guide.html#toJSON
- http://mongoosejs.com/docs/guide.html#toObject
Вы можете абстрагировать это в BaseSchema, все ваши модели затем расширять/вызывать, чтобы сохранить логику в одном месте. Я написал это выше при создании приложения Ember/Node/Mongoose, поскольку Ember действительно предпочитает иметь поле «id» для работы.
Schema.set('toObject', { virtuals: true })
, чтобы иметь возможность видеть виртуальные выходные данные при использовании console.log(obj)
.
- person Tom; 26.03.2014
toObject
. mongoosejs.com/docs/guide.html#toObject
- person Dave Jensen; 15.05.2014
const companyCollection = mongoose.Schema({});
с помощью ExpressJs
- person 151291; 16.01.2019
id
. mongoosejs.com/docs/guide.html#id
- person David Ferreira; 30.03.2019
Начиная с Mongoose v4.0 часть этой функциональности поддерживается по умолчанию. Больше не требуется вручную добавлять виртуальное поле id
, как объяснил @Pascal Zajac.
Mongoose назначает каждой из ваших схем виртуальный геттер идентификатора по умолчанию, который возвращает поле _id документов, приведенное к строке, или, в случае ObjectIds, его hexString. Если вы не хотите, чтобы получатель идентификатора добавлялся в вашу схему, вы можете отключить его, передав эту опцию во время создания схемы. Источник
Однако для экспорта этого поля в формат JSON по-прежнему необходимо включить сериализацию виртуальных полей:
Schema.set('toJSON', {
virtuals: true
});
Я использовал это:
schema.set('toJSON', {
virtuals: true,
versionKey:false,
transform: function (doc, ret) { delete ret._id }
});
Я думаю, было бы здорово, если бы они автоматически подавляли _id, когда для виртуалов установлено значение true.
const UserSchema = new Schema({ stuff }); UserSchema.set("toJSON", { virtuals: true, versionKey: false, transform: function(doc, ret) { delete ret._id; } }); const User = model("user", UserSchema);
- person user3152459; 15.03.2020
lean: true
при извлечении документов из базы данных.
- person coatesap; 17.06.2020
Вот альтернативная версия ответа, предоставленного пользователем @user3087827. Если вы обнаружите, что schema.options.toJSON
не определено, вы можете использовать:
schema.set('toJSON', {
transform: function (doc, ret, options) {
ret.id = ret._id;
delete ret._id;
delete ret.__v;
}
});
//Transform
Schema.options.toJSON.transform = function (doc, ret, options) {
// remove the _id of every document before returning the result
ret.id = ret._id;
delete ret._id;
delete ret.__v;
}
есть свойство «Schema.options.toObject.transform», чтобы сделать обратное, или вы можете просто настроить его как виртуальный идентификатор.
Если вы хотите использовать id
вместо _id
глобально, вы можете установить toJSON
config для объекта mongoose(начиная с версии 5.3):
mongoose.set('toJSON', {
virtuals: true,
transform: (doc, converted) => {
delete converted._id;
}
});
Для этой цели я создал простой в использовании плагин, который применяю ко всем мои проекты и все схемы по всему миру. Он преобразует _id
в id
, а также удаляет параметр __v
.
Итак, он конвертирует:
{
"_id": "400e8324a71d4410b9dc3980b5f8cdea",
"__v": 2,
"name": "Item A"
}
К более простому и чистому:
{
"id": "400e8324a71d4410b9dc3980b5f8cdea",
"name": "Item A"
}
Использование в качестве глобального плагина:
const mongoose = require('mongoose');
mongoose.plugin(require('meanie-mongoose-to-json'));
Или для конкретной схемы:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const MySchema = new Schema({});
MySchema.plugin(require('meanie-mongoose-to-json'));
Надеюсь, это поможет кому-то.
Заменить метод по умолчанию toJSON
новым:
schema.method('toJSON', function () {
const { __v, _id, ...object } = this.toObject();
object.id = _id;
return object;
});
Существует также normalize-mongoose
простой пакет, который удаляет _id
и __v
за вас.
Из чего-то вроде этого:
import mongoose from 'mongoose';
import normalize from 'normalize-mongoose';
const personSchema = mongoose.Schema({ name: String });
personSchema.plugin(normalize);
const Person = mongoose.model('Person', personSchema);
const someone = new Person({ name: 'Abraham' });
const result = someone.toJSON();
console.log(result);
Итак, допустим, у вас есть что-то вроде этого:
{
"_id": "5dff03d3218b91425b9d6fab",
"name": "Abraham",
"__v": 0
}
Вы получите этот вывод:
{
"id": "5dff03d3218b91425b9d6fab",
"name": "Abraham"
}
Вы также можете использовать агрегатную функцию при поиске возвращаемых элементов. $project позволит вам создавать поля, которые вы можете сделать, и присвоить их _id.
<model>.aggregate([{$project: {_id: 0, id: '$_id'}], (err, res) => {
//
})
Если вы используете lodash для выбора нужных элементов, это сработает для вас.
UserSchema.virtual('id').get(function(){
return this._id.toHexString();
});
UserSchema.set('toObject', { virtuals: true })
UserSchema.methods.toJSON = function() {
return _.pick(
this.toObject(),
['id','email','firstName','lastName','username']
);
Создайте базовую схему
import { Schema } from "mongoose";
export class BaseSchema extends Schema {
constructor(sche: any) {
super(sche);
this.set('toJSON', {
virtuals: true,
transform: (doc, converted) => {
delete converted._id;
}
});
}
}
Теперь в вашей модели мангуста используйте BaseSchema
вместо Schema
import mongoose, { Document} from 'mongoose';
import { BaseSchema } from '../../helpers/mongoose';
const UserSchema = new BaseSchema({
name: String,
age: Number,
});
export interface IUser {
name: String,
age: Number,
}
interface IPlanModel extends IUser, Document { }
export const PlanDoc = mongoose.model<IPlanModel>('User', UserSchema);
Реализация машинописного текста ответа @Pascal Zajac
Есть еще один драйвер, который делает это http://alexeypetrushin.github.com/mongo-lite set convertId
вариант в истину. Дополнительные сведения см. в разделе «Значения по умолчанию и настройки».
Переопределить toJSON
method для конкретной схемы модели. https://mongoosejs.com/docs/api.html#schema_Schema-method
YourSchema.methods.toJSON = function () {
return {
id: this._id,
some_field: this.some_field,
created_at: this.createdAt
}
}
Вы также можете использовать предварительный хук «сохранить»:
TouSchema.pre('save', function () {
if (this.isNew) {
this._doc.id = this._id;
}
}