如何在猫鼬中将 ObjectId 设置为数据类型

在 mongoHQ 和猫鼬上使用 node.js、 mongodb。我正在为类别设置模式。我想使用文档 ObjectId 作为分类 ID。

var mongoose = require('mongoose');


var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var Schema_Category = new Schema({
categoryId  : ObjectId,
title       : String,
sortIndex   : String
});

然后我就跑

var Category = mongoose.model('Schema_Category');
var category = new Category();
category.title = "Bicycles";
category.sortIndex = "3";


category.save(function(err) {
if (err) { throw err; }
console.log('saved');
mongoose.disconnect();
});

请注意,我没有为 typeyId 提供值。我假设 monose 将使用模式来生成它,但是文档使用通常的“ _ id”而不是“ typeyId”。我做错了什么?

152275 次浏览

与传统的 RBDM 不同,mongoDB 不允许将任何随机字段定义为主键,_ id 字段必须存在于所有标准文档中。

因此,创建一个单独的 uuid 字段是没有意义的。

在猫鼬中,ObjectId 类型不用于创建新的 uuid,而是主要用于引用其他文档。

这里有一个例子:

var mongoose = require('mongoose');


var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var Schema_Product = new Schema({
categoryId  : ObjectId, // a product references a category _id with type ObjectId
title       : String,
price       : Number
});

正如您所看到的,用 ObjectId 填充 typeyId 没有多大意义。

但是,如果您确实想要一个名称很好的 uuid 字段,monose 提供了允许您代理(引用)字段的虚拟属性。

看看这个:

var mongoose = require('mongoose');


var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var Schema_Category = new Schema({
title       : String,
sortIndex   : String
});


Schema_Category.virtual('categoryId').get(function() {
return this._id;
});

因此,现在,无论何时调用 classy.typeyId,monose 都只返回 _ id。

您还可以创建一个“ set”方法来设置虚拟属性,查看 < a href = “ http://mongoosejs.com/docs/virals.html”> 这个链接 了解更多信息

我在寻找题目的不同答案,所以也许其他人也会这么想。

要将类型设置为 ObjectId (例如,您可以引用 author作为 book的作者) ,您可以这样做:

const Book = mongoose.model('Book', {
author: {
type: mongoose.Schema.Types.ObjectId, // here you set the author ID
// from the Author colection,
// so you can reference it
required: true
},
title: {
type: String,
required: true
}
});

使用 ObjectId 的解决方案

// usermodel.js


const mongoose = require('mongoose')
const Schema = mongoose.Schema
const ObjectId = Schema.Types.ObjectId




let UserSchema = new Schema({
username: {
type: String
},
events: [{
type: ObjectId,
ref: 'Event' // Reference to some EventSchema
}]
})


UserSchema.set('autoIndex', true)


module.exports = mongoose.model('User', UserSchema)

用猫鼬的 人口密度

// controller.js


const mongoose = require('mongoose')
const User = require('./usermodel.js')


let query = User.findOne({ name: "Person" })


query.exec((err, user) => {
if (err) {
console.log(err)
}


user.events = events
// user.events is now an array of events
})

@ dex 提供的解决方案对我很有效。但是我想添加一些对我也有用的东西: 使用

let UserSchema = new Schema({
username: {
type: String
},
events: [{
type: ObjectId,
ref: 'Event' // Reference to some EventSchema
}]
})

如果要创建的是 Array 引用,则为。但是如果你想要的是一个 Object 引用,我认为你无论如何都会找到它,像这样从 价值支柱中去掉括号:

let UserSchema = new Schema({
username: {
type: String
},
events: {
type: ObjectId,
ref: 'Event' // Reference to some EventSchema
}
})

仔细看这两个片段。在第二种情况下,键事件的值支持在对象 def 上没有括号。

您可以直接定义 ObjectId

Var Schema = 新猫鼬 模式。类型。 ObjectId, 标题: 字符串, SortIndex: String })

注意: 您需要导入猫鼬模块

另一种可能的方法是将您的 _ id 转换为您喜欢的内容。

下面是我为一个项目实现的 Page-Document 的一个例子:

interface PageAttrs {
label: string
// ...
}


const pageSchema = new mongoose.Schema<PageDoc>(
{
label: {
type: String,
required: true
}
// ...
},
{
toJSON: {
transform(doc, ret) {
// modify ret directly
ret.id = ret._id
delete ret._id
}
}
}
)


pageSchema.statics.build = (attrs: PageAttrs) => {
return new Page({
label: attrs.label,
// ...
})
}


const Page = mongoose.model<PageDoc, PageModel>('Page', pageSchema)


现在您可以直接访问属性‘ id’,例如在单元测试中,如下所示:

it('implements optimistic concurrency', async () => {
const page = Page.build({
label: 'Root Page'
// ...
})


await page.save()


const firstInstance = await Page.findById(page.id)
const secondInstance = await Page.findById(page.id)


firstInstance!.set({ label: 'Main Page' })
secondInstance!.set({ label: 'Home Page' })


await firstInstance!.save()


try {
await secondInstance!.save()
} catch (err) {
console.error('Error:', err)
return
}


throw new Error('Should not reach this point')
})