2

如果我有两个模式,一个将嵌入到另一个中:

var mongoose = require("mongoose");
var Schema = mongoose.Schema;

// Will embed this in the personSchema below
var addressSchema = new Schema({
    street: String,
    city: String,
    state: {
        type: String,
        uppercase: true
    },
    zip: Number
});

var personSchema = new Schema({
    firstName: {
        type: String,
        required: true
    },
    lastName: {
        type: String,
        required: true
    },
    emailAddress: {
        type: String,
        lowercase: true
    },
    phoneNumber: Number,
    address: addressSchema
});

module.exports = mongoose.model("Person", personSchema);

我似乎无法让uppercase: true嵌入文档工作 - 没有引发错误,但它根本不会大写 state 属性。或任何类似的选择。

我一直在搜索 Mongoose 文档,但也许我只是没有找到它提到在子文档上设置这些类型的附加选项不起作用的地方。

4

2 回答 2

1

直到最近,如果您尝试像您正在做的那样直接将一个模式嵌入到另一个模式中,Mongoose 会抛出异常。看起来它现在得到了部分支持,但显然不适用于这种情况。

您可以通过addressSchemaaddress.personSchema

var addressObject = {
    street: String,
    city: String,
    state: {
        type: String,
        uppercase: true
    },
    zip: Number
};
var addressSchema = new Schema(addressObject);

var personSchema = new Schema({
    firstName: {
        type: String,
        required: true
    },
    lastName: {
        type: String,
        required: true
    },
    emailAddress: {
        type: String,
        lowercase: true
    },
    phoneNumber: Number,
    address: addressObject
});
于 2015-12-05T15:04:25.070 回答
1

这是否是最好的方法并不肯定,但我添加了一个预保存钩子(根据评论中@nbro的建议),这似乎有效:

var addressSchema = new Schema({
    street: String,
    city: String,
    state: {
        type: String,
        uppercase: true
    },
    zip: Number
});

addressSchema.pre("save", function (next) {
    this.state = this.state.toUpperCase();
    next();
});

var personSchema = new Schema({
    firstName: {
        type: String,
        required: true
    },
    lastName: {
        type: String,
        required: true
    },
    emailAddress: {
        type: String,
        lowercase: true
    },
    phoneNumber: Number,
    address: addressSchema
});

更新#1:

我似乎能够找到很多人在没有任何额外验证(required: true)或更改(uppercase: true)发生的情况下嵌入简单模式的案例。虽然上述解决方案确实有效,但似乎没有必要。我可能应该做的只是放入对象文字以嵌入信息:

var personSchema = new Schema({
    ...
    address: {
        street: String,
        city: String,
        state: {
            type: String,
            uppercase: true
        },
        zip: Number
    }
});

似乎使用单独模式的唯一充分理由是,如果您绝对需要嵌入数据具有_id属性,并且您不需要向任何属性添加额外的验证或更改选项。如果您需要_id我猜您可能不应该嵌入数据,而是将其保存为单独的对象并进行引用。

当我发现新的信息和最佳实践时,我会不断更新。

更新#2:

如果您想在嵌入文档中包含验证,例如使address属性成为必需,您将不得不单独进行,如这篇关于它的非常好的博客文章中所述。

于 2015-12-04T22:29:00.317 回答