如何在猫鼬中将 ObjectId 设置为数据类型
Posted
技术标签:
【中文标题】如何在猫鼬中将 ObjectId 设置为数据类型【英文标题】:How to set ObjectId as a data type in mongoose 【发布时间】:2011-12-28 01:13:42 【问题描述】:在 mongoHQ 和 mongoose 上使用 node.js、mongodb。我正在为类别设置架构。我想使用文档 ObjectId 作为我的 categoryId。
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();
);
请注意,我没有为 categoryId 提供值。我假设猫鼬将使用模式来生成它,但文档具有通常的“_id”而不是“categoryId”。我做错了什么?
【问题讨论】:
【参考方案1】:与传统的 RBDM 不同,mongoDB 不允许您将任何随机字段定义为主键,所有标准文档都必须存在 _id 字段。
因此,创建单独的 uuid 字段没有意义。
在 mongoose 中,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 填充 categoryId 没有多大意义。
但是,如果您确实想要一个命名良好的 uuid 字段,mongoose 提供了允许您代理(引用)字段的虚拟属性。
检查一下:
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;
);
所以现在,每当您调用 category.categoryId 时,mongoose 只会返回 _id。
你也可以创建一个“set”方法来设置虚拟属性,查看this link 了解更多信息
【讨论】:
设置虚拟属性后,我尝试了:db.cats.find(categoryId: ObjectId("the id")) 但得到了空结果。当我使用 db.cats.find(_id: ObjectId("the id")) 我确实得到了一个文档。所以看起来虚拟属性不能用于搜索。我认为,如果可以使用清晰的名称引用每个 ID,而不是使用 _id 来表示所有内容,那么管理代码会更容易。只是一个想法......【参考方案2】:我一直在为问题标题寻找不同的答案,所以也许其他人也会。
要将 type 设置为 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
);
【讨论】:
【参考方案3】:我使用 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)
使用猫鼬的populate方法
// 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
)
【讨论】:
如何在事件字段中添加默认值?【参考方案4】:@dex 提供的解决方案对我有用。但我想添加一些对我也有用的东西:使用
let UserSchema = new Schema(
username:
type: String
,
events: [
type: ObjectId,
ref: 'Event' // Reference to some EventSchema
]
)
如果您要创建的是数组引用。但是,如果您想要的是一个对象引用,我认为您可能正在寻找它,请从 value 属性中删除括号,如下所示:
let UserSchema = new Schema(
username:
type: String
,
events:
type: ObjectId,
ref: 'Event' // Reference to some EventSchema
)
看好2个sn-ps。第二种情况,key events 的 value prop 在对象 def 上没有括号。
【讨论】:
【参考方案5】:可以直接定义ObjectId
var Schema = new mongoose.Schema( categoryId : mongoose.Schema.Types.ObjectId, 标题:字符串, 排序索引:字符串 )
注意:你需要导入猫鼬模块
【讨论】:
以上是关于如何在猫鼬中将 ObjectId 设置为数据类型的主要内容,如果未能解决你的问题,请参考以下文章