MongoDB:输出“id”而不是“_id”

发布于 2024-11-29 05:12:34 字数 42 浏览 0 评论 0原文

我正在使用猫鼬(节点),输出 id 而不是 _id 的最佳方式是什么?

I am using mongoose (node), what is the best way to output id instead of _id?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(20

熊抱啵儿 2024-12-06 05:12:34

鉴于您使用的是 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 时,它将包含一个与 Mongo 生成的 _id 字段匹配的“id”字段。同样,您可以以相同的方式设置 toObject 的行为。

请参阅:

您可以将其抽象为然后扩展/调用所有模型的 BaseSchema 以将逻辑保留在一处。我在创建 Ember/Node/Mongoose 应用程序时编写了上述内容,因为 Ember 确实更喜欢使用“id”字段。

Given you're using Mongoose, you can use 'virtuals', which are essentially fake fields that Mongoose creates. They're not stored in the DB, they just get populated at run time:

// Duplicate the ID field.
Schema.virtual('id').get(function(){
    return this._id.toHexString();
});

// Ensure virtual fields are serialised.
Schema.set('toJSON', {
    virtuals: true
});

Any time toJSON is called on the Model you create from this Schema, it will include an 'id' field that matches the _id field Mongo generates. Likewise you can set the behaviour for toObject in the same way.

See:

You can abstract this into a BaseSchema all your models then extend/invoke to keep the logic in one place. I wrote the above while creating an Ember/Node/Mongoose app, since Ember really prefers to have an 'id' field to work with.

给我一枪 2024-12-06 05:12:34

我用过这个:

schema.set('toJSON', {
  virtuals: true,
  versionKey:false,
  transform: function (doc, ret) {   delete ret._id  }
});

我认为如果它们在 virtuals 为 true 时自动抑制 _id ,那就太好了。

I used this :

schema.set('toJSON', {
  virtuals: true,
  versionKey:false,
  transform: function (doc, ret) {   delete ret._id  }
});

I think it would be great if they automatically suppress _id when virtuals is true.

土豪 2024-12-06 05:12:34

从 Mongoose v4.0 开始,此功能的一部分是开箱即用的支持。正如 @Pascal Zajac 所解释的,不再需要手动添加虚拟 id 字段。

默认情况下,Mongoose 会为每个模式分配一个 id 虚拟 getter
它返回文档 _id 字段转换为字符串,或者在这种情况下
ObjectIds 的十六进制字符串。如果你不想添加 id getter
您的模式,您可以在模式中传递此选项来禁用它
施工时间。 来源

但是,要导出此字段到JSON ,仍然需要启用虚拟字段的序列化:

Schema.set('toJSON', {
    virtuals: true
});

As of Mongoose v4.0 part of this functionality is supported out of the box. It's no longer required to manually add a virtual id field as explained by @Pascal Zajac.

Mongoose assigns each of your schemas an id virtual getter by default
which returns the documents _id field cast to a string, or in the case
of ObjectIds, its hexString. If you don't want an id getter added to
your schema, you may disable it passing this option at schema
construction time. Source

However, to export this field to JSON, it's still required to enable serialization of virtual fields:

Schema.set('toJSON', {
    virtuals: true
});
可爱咩 2024-12-06 05:12:34

我在我的模型上创建了一个 toClient() 方法来执行此操作。这也是重命名/删除您不想发送给客户端的其他属性的好地方:

Schema.method('toClient', function() {
    var obj = this.toObject();

    //Rename fields
    obj.id = obj._id;
    delete obj._id;

    return obj;
});

I create a toClient() method on my models where I do this. It's also a good place to rename/remove other attributes you don't want to send to the client:

Schema.method('toClient', function() {
    var obj = this.toObject();

    //Rename fields
    obj.id = obj._id;
    delete obj._id;

    return obj;
});
苍白女子 2024-12-06 05:12:34

这是@user3087827 提供的答案的替代版本。如果您发现 schema.options.toJSON 未定义,那么您可以使用:

schema.set('toJSON', {
     transform: function (doc, ret, options) {
         ret.id = ret._id;
         delete ret._id;
         delete ret.__v;
     }
}); 

Here is an alternative version of the answer provided by @user3087827. If you find that schema.options.toJSON is undefined then you can use:

schema.set('toJSON', {
     transform: function (doc, ret, options) {
         ret.id = ret._id;
         delete ret._id;
         delete ret.__v;
     }
}); 
半衬遮猫 2024-12-06 05:12:34
//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。

//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;
}

there is a "Schema.options.toObject.transform" property to do the reverse or you could just setup as a virtual id.

夏末的微笑 2024-12-06 05:12:34

如果您想使用 id 而不是 _id 全局,那么您可以在 mongoose 对象上设置 toJSON 配置(从 v5.3 开始):

mongoose.set('toJSON', {
  virtuals: true,
  transform: (doc, converted) => {
    delete converted._id;
  }
});

If you want to use id instead of _id globally then you can set toJSON config on mongoose object(starting from v5.3):

mongoose.set('toJSON', {
  virtuals: true,
  transform: (doc, converted) => {
    delete converted._id;
  }
});
扛刀软妹 2024-12-06 05:12:34

还有 normalize-mongoose 一个简单的包,可以删除 _id< /code> 和 __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"
}

There is also normalize-mongoose a simple package that removes _id and __v for you.

From something like this:

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);

So let's say you have something like this:

{
  "_id": "5dff03d3218b91425b9d6fab",
  "name": "Abraham",
  "__v": 0
}

You will get this output:

{
  "id": "5dff03d3218b91425b9d6fab",
  "name": "Abraham"
}
波浪屿的海角声 2024-12-06 05:12:34

用新方法覆盖默认方法 toJSON

schema.method('toJSON', function () {
   const { __v, _id, ...object } = this.toObject();
   object.id = _id;
   return object;
});

Overwrite default method toJSON by new one:

schema.method('toJSON', function () {
   const { __v, _id, ...object } = this.toObject();
   object.id = _id;
   return object;
});
美人骨 2024-12-06 05:12:34

为此,我创建了一个易于使用的插件,我将其应用于所有我的项目以及全球所有架构。它将 _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'));

希望这对某人有帮助。

I created an easy to use plugin for this purpose that I apply for all my projects and to all schema's globally. It converts _id to id and strips the __v parameter as well.

So it converts:

{
  "_id": "400e8324a71d4410b9dc3980b5f8cdea",
  "__v": 2,
  "name": "Item A"
}

To a simpler and cleaner:

{
  "id": "400e8324a71d4410b9dc3980b5f8cdea",
  "name": "Item A"
}

Usage as a global plugin:

const mongoose = require('mongoose');
mongoose.plugin(require('meanie-mongoose-to-json'));

Or for a specific schema:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const MySchema = new Schema({});
MySchema.plugin(require('meanie-mongoose-to-json'));

Hope this helps someone.

聊慰 2024-12-06 05:12:34

您还可以在搜索要返回的项目时使用聚合函数。 $project 将允许您创建字段,您可以执行此操作并将其分配给 _id。

<model>.aggregate([{$project: {_id: 0, id: '$_id'}], (err, res) => {
 // 
})

You can also use the aggregate function when searching for items to return. $project will allow you to create fields, which you can do and assign it to _id.

<model>.aggregate([{$project: {_id: 0, id: '$_id'}], (err, res) => {
 // 
})
冷心人i 2024-12-06 05:12:34

创建基本架构

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 答案的 Typescript 实现

Create a base schema

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;
        }
    });
        }
    
    }

Now in your mongoose model, use BaseSchema instead of 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);

Typescript implementation of @Pascal Zajac answer

長街聽風 2024-12-06 05:12:34

如果您使用 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']
  );

If you are using lodash to pick the elements you want, this will work for you.

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']
  );
淡淡離愁欲言轉身 2024-12-06 05:12:34

覆盖特定模型架构的 toJSON 方法。
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
  }
}

Override toJSONmethod for specific model schema.
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
  }
}
纵情客 2024-12-06 05:12:34

此配置使用 nestjs + mongoose

@Schema({ 
    versionKey: false, // __v field not saving to db
    timestamps: true,  // auto add both fields  'createdAt' and 'updatedAt'
    toJSON: {
        transform(doc, ret, options) {
            ret.id = ret._id;
            delete ret._id;
        },
    }
})

使用以下字段保存到数据库:


_id: 65b4df698bec4f57043f7bc3
email: "[email protected]"
password :"$argon2id$v"
role: "user"

对客户端的响应,id 替换为 _id

id: 65b4df698bec4f57043f7bc3 // replaced with _id
email: "[email protected]"
password :"$argon2id$v"
role: "user"

this config with nestjs + mongoose :

@Schema({ 
    versionKey: false, // __v field not saving to db
    timestamps: true,  // auto add both fields  'createdAt' and 'updatedAt'
    toJSON: {
        transform(doc, ret, options) {
            ret.id = ret._id;
            delete ret._id;
        },
    }
})

saved to database with this fields:


_id: 65b4df698bec4f57043f7bc3
email: "[email protected]"
password :"$argon2id$v"
role: "user"

response to client , id replaced with _id

id: 65b4df698bec4f57043f7bc3 // replaced with _id
email: "[email protected]"
password :"$argon2id$v"
role: "user"
诗酒趁年少 2024-12-06 05:12:34

还有另一个驱动程序可以执行此操作 http://alexeypetrushin.github.com/mongo-lite 设置 < code>convertId 选项设置为 true。有关更多详细信息,请参阅“默认值和设置”部分。

There's another driver that does that http://alexeypetrushin.github.com/mongo-lite set convertId option to true. See "Defaults & Setting" section for more details.

停顿的约定 2024-12-06 05:12:34

默认情况下,Mongoose 为每个模式分配一个 id 虚拟 getter,该 getter 返回文档的 _id 字段转换为字符串,或者在 ObjectIds 的情况下,返回其十六进制字符串。

https://mongoosejs.com/docs/guide.html

Mongoose assigns each of your schemas an id virtual getter by default which returns the document's _id field cast to a string, or in the case of ObjectIds, its hexString.

https://mongoosejs.com/docs/guide.html

满身野味 2024-12-06 05:12:34

方法一:

const CartSchema = new Schema({
    userId: {
        type: String,
        required: true
    },
    products: [{
        productId: {
            type: String
        },
        quantity: {
            type: Number,
            default: 1
        },
    }]
}, {
    toJSON: {
        virtuals: true,
        transform(doc, ret) {
            delete ret.__v
            delete ret.password
            ret.id = ret._id
            delete ret._id
        }
    }
})
  1. 将_id改为id:ret.id = ret._id
  2. 删除_id:delete ret._id

方法二:

Method 1:

const CartSchema = new Schema({
    userId: {
        type: String,
        required: true
    },
    products: [{
        productId: {
            type: String
        },
        quantity: {
            type: Number,
            default: 1
        },
    }]
}, {
    toJSON: {
        virtuals: true,
        transform(doc, ret) {
            delete ret.__v
            delete ret.password
            ret.id = ret._id
            delete ret._id
        }
    }
})
  1. Change _id to id: ret.id = ret._id
  2. Delete _id: delete ret._id

Method 2:

草莓酥 2024-12-06 05:12:34

您还可以使用 pre 'save' 挂钩:

TouSchema.pre('save', function () {      
  if (this.isNew) {
    this._doc.id = this._id;      
  } 
}

You can also use pre 'save' hook:

TouSchema.pre('save', function () {      
  if (this.isNew) {
    this._doc.id = this._id;      
  } 
}
苯莒 2024-12-06 05:12:34
JSON.parse(JSON.stringify(doc.toJSON()))
JSON.parse(JSON.stringify(doc.toJSON()))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文