【问题标题】:mongoose: how to choose one of two types猫鼬:如何选择两种类型之一
【发布时间】:2020-01-09 15:10:06
【问题描述】:

我想在我的网站上拥有两种类型的用户 - 普通用户和网页设计师。

如何在 mongoose 架构中指定可以是两个值的类型 - “普通”或“设计器”

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    两种类型之间的“选择”完全取决于您的意思。

    在简单的情况下,您只希望多个值对选项列表中的一个属性有效,那么您可以使用enum 使唯一的值成为一种可能性:

    var userSchema = new Schema({
      "type": { "type": String, "enum": ["normal", "developer"] }
    });
    

    这允许基本验证属性必须包含这些值之一并且仅包含这些值之一。尝试设置为另一个值或省略该值将导致验证错误。

    但是,如果您想要更高级的东西,例如本质上不同的对象,每个“类型”都有扩展字段,那么“鉴别器”可能适合您。

    这允许您在普通“用户”和“开发人员”之间拥有不同的属性,例如开发人员的项目列表。它们都将保存在同一个集合中,但它们是具有自己的架构定义和规则的一流对象:

    var util = require('util'),
        async = require('async'),
        mongoose = require('mongoose'),
        Schema = mongoose.Schema;
    
    mongoose.connect('mongodb://localhost/test');
    
    function BaseSchema() {
      Schema.apply(this,arguments);
    
      this.add({
        name: String,
        createdAt: { type: Date, default: Date.now }
      });
    }
    
    util.inherits(BaseSchema,Schema);
    
    var userSchema = new BaseSchema();
    var developerSchema = new BaseSchema({
      projects: [String]
    });
    
    var User = mongoose.model('User',userSchema),
        Developer = User.discriminator( 'Developer', developerSchema );
    
    async.series(
      [
        function(callback) {
          User.remove({},callback);
        },
        function(callback) {
          async.eachSeries(
            [
              { "role": "User", "name": "Bill" },
              { "role": "Developer", "name": "Ted", "projects": [
                "apples", "oranges" ] }
            ],
            function(item,callback) {
              mongoose.model(item.role).create(item,callback);
            },
            callback
          );
        },
        function(callback) {
          User.find().exec(function(err,docs) {
            console.log(docs)
            callback(err);
          });
        }
      ],
      function(err) {
        if (err) throw err;
        mongoose.disconnect();
      }
    );
    

    输出显示同一集合中的两个对象:

    [ { _id: 55ff7b22f1ff34f915cc8312,
        name: 'Bill',
        __v: 0,
        createdAt: Mon Sep 21 2015 13:36:02 GMT+1000 (AEST) },
      { _id: 55ff7b22f1ff34f915cc8313,
        name: 'Ted',
        __v: 0,
        __t: 'Developer',
        createdAt: Mon Sep 21 2015 13:36:02 GMT+1000 (AEST),
        projects: [ 'apples', 'oranges' ] } ]
    

    请注意,“开发人员”“Ted”有另一个字段存储为__t,其中包含模型的鉴别器值。这允许mongoose 在读取时应用魔法并投射到正确的对象。

    这也意味着每个模型都可以独立使用,操作如下:

    Developer.find().exec(function(err,developers) { });
    
    Developer.create(newDev,function(err,developer) { });
    

    分别“神奇地插入”“类型”,以便每个操作仅找到或创建匹配的 __t: 'Developer' 对象。

    所以enum 将限制可能的值,discriminator() 允许您为整个对象设置完全独立的定义。这取决于您的意思是哪种形式,但两者都很好用。

    【讨论】:

    • 正在为我们的部署系统寻找这样的功能......感谢您的详细指南。肯定会检查一下
    猜你喜欢
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 2021-12-15
    • 2021-08-11
    • 2020-12-04
    • 2020-01-10
    相关资源
    最近更新 更多