猫鼬:如何选择两种类型之一

Lou*_*ost 1 mongoose mongodb node.js

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

我如何在猫鼬模式中指定一个可以是两个值的类型——“正常”或“设计者”

Bla*_*ven 6

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

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

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

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

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

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

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();
  }
);
Run Code Online (Sandbox Code Playgroud)

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

[ { _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' ] } ]
Run Code Online (Sandbox Code Playgroud)

请注意,“开发人员”的“Ted”存储了另一个字段,__t用于保存模型的鉴别器值。这允许mongoose在读取转换为正确对象时应用魔法。

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

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

Developer.create(newDev,function(err,developer) { });
Run Code Online (Sandbox Code Playgroud)

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

Soenum会给你一个对可能值的限制,并discriminator()允许你为整个对象设置完全独立的定义。这取决于您指的是哪种形式,但两者都很好用。