【问题标题】:How to set ObjectId as a data type in mongoose如何在猫鼬中将 ObjectId 设置为数据类型
【发布时间】: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”。我做错了什么?

【问题讨论】:

    标签: node.js mongoose


    【解决方案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, 标题:字符串, 排序索引:字符串 })

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-10-07
          • 2017-10-24
          • 2022-09-28
          • 1970-01-01
          • 2017-04-25
          • 2020-05-25
          • 2017-02-26
          • 2019-09-16
          相关资源
          最近更新 更多