- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
当我有一个具有多类型属性的集合架构时。比如可以是数字也可以是字符串
我为此使用了 mongoose 的混合类型,但所有验证都消失了。
问题:
var employeeSchema = mongoose.Schema({
_id:false,
title:string,
...
});
EmployeeSchema.methods.(....)//add some methods
var GroupSchema = ({
visitor: {}, // visitor can be an Employee schema or a string of person name
note: string,
time: Date
},{collection:'group'});
如何在 groupSchema 中定义访问者:
最佳答案
您在这里所追求的实际上是一种“多态性”形式,或者我们通常如何在数据库中将其实现为“鉴别器”。这里的基础知识是一种形式的 Object 继承自另一种形式,但它是自己的对象,具有自己独特的属性以及相关联的方法。
这实际上比仅仅区分普通的“字符串”和更具体的对象更好,而且实现起来相当简单。例如:
var async = require('async'),
util = require('util'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/company');
function BaseSchema() {
Schema.apply(this,arguments);
this.add({
name: String
});
}
util.inherits(BaseSchema,Schema);
var personSchema = new BaseSchema();
personSchema.methods.speak = function() {
console.log( "my name is %s",this.name );
};
var employeeSchema = new BaseSchema({
title: String
});
employeeSchema.methods.speak = function() {
console.log( "my name is %s, and my title is %s",this.name,this.title );
};
var groupSchema = new Schema({
visitor: { "type": Schema.Types.ObjectId, "ref": "Person" },
note: String,
time: { "type": Date, "default": Date.now }
});
var Person = mongoose.model( 'Person', personSchema ),
Employee = Person.discriminator( 'Employee', employeeSchema ),
Group = mongoose.model( 'Group', groupSchema );
async.waterfall(
[
// Clean data
function(callback) {
async.each([Person,Group],function(model,callback) {
model.remove(callback);
},callback);
},
// Add a person
function(callback) {
var person = new Person({ "name": "Bob" });
person.save(function(err,person) {
callback(err,person);
});
},
// Add an employee
function(person,callback) {
var employee = new Employee({ "name": "Sarah", "title": "Manager" });
employee.save(function(err,employee) {
callback(err,person,employee);
});
},
// Add person to group
function(person,employee,callback) {
var group = new Group({
visitor: person
});
group.save(function(err) {
callback(err,employee);
});
},
// Add employee to group
function(employee,callback) {
var group = new Group({
visitor: employee
});
group.save(function(err) {
callback(err);
});
},
// Get groups populated
function(callback) {
Group.find().populate('visitor').exec(function(err,group) {
console.dir(group);
group.forEach(function(member) {
member.visitor.speak();
});
callback(err);
});
}
],
function(err) {
if (err) throw err;
mongoose.disconnect();
}
);
这里是非常基本的输出:
[ { _id: 55d06d984a4690ca1f0d73ed,
visitor: { _id: 55d06d984a4690ca1f0d73eb, name: 'Bob', __v: 0 },
__v: 0,
time: Sun Aug 16 2015 21:01:44 GMT+1000 (AEST) },
{ _id: 55d06d984a4690ca1f0d73ee,
visitor:
{ _id: 55d06d984a4690ca1f0d73ec,
name: 'Sarah',
title: 'Manager',
__v: 0,
__t: 'Employee' },
__v: 0,
time: Sun Aug 16 2015 21:01:44 GMT+1000 (AEST) } ]
my name is Bob
my name is Sarah, and my title is Manager
简而言之,这里有两种“类型”,即“人”和“雇员”。 “人”当然是每个人的基本类型,因此可以有一些基本属性,如果需要的话甚至可以有方法。 “Employee”继承自基础“Person”,因此共享任何属性和方法,并且能够定义自己的属性和方法。
在这里设置 mongoose 模型时,这些是重要的几行:
var Person = mongoose.model( 'Person', personSchema ),
Employee = Person.discriminator( 'Employee', employeeSchema ),
请注意,“Employee”不使用标准的 mongoose.model
构造函数,而是调用 Person.discriminator
。这做了一件特别的事情,实际上“Employee”实际上与“Person”模型共享,但有不同的信息告诉 mongoose 这实际上是一个“Employee”。
还要注意 groupSchema
中“visitor”的构造:
visitor: { "type": Schema.Types.ObjectId, "ref": "Person" },
如前所述,“Person”和“Employee”实际上与“Person”共享相同的基础模型,但具有一些特定的特征。所以这里的引用告诉 Mongoose 从这个模型中解析存储的 ObjectId 值。
当您调用 .populate()
时,这样做的好处就显而易见了,就像 list 后面所做的那样。当这些引用中的每一个都被解析时,正确的对象类型被替换为那里的值。当 .speak()
方法在“访问者”的每个对象上调用时,这一点变得很明显。
my name is Bob
my name is Sarah, and my title is Manager
您还可以获得其他一些很棒的东西,因为 mongoose 可以做一些事情,例如将“雇员”视为模型并“自动”过滤掉任何查询中不是雇员的任何对象。同样,使用“Person”模型也会显示其中的所有类型(它们由“__t”属性和它的值区分),因此您也可以在各种查询过程中利用它。
因此,如果您不喜欢引用,或者通常只是喜欢将所有数据保存在“组”集合中,而不为其他“人”数据单独收集,那么这也是可能的。
这里您真正需要的只是对 list 进行一些更改,特别是在“访问者”作为“混合”类型的模式定义中:
visitor: Schema.Types.Mixed,
然后不用调用 .populate()
因为所有的数据都已经存在了,你只需要做一些手动的“类型转换”,这实际上很简单:
group.forEach(function(member) {
member.visitor = (member.visitor.hasOwnProperty("__t"))
? mongoose.model(member.visitor.__t)(member.visitor)
: Person(member.visitor);
member.visitor.speak();
});
然后一切都与嵌入式数据一起“流畅地”工作。
对于使用嵌入式数据的完整列表:
var async = require('async'),
util = require('util'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/company');
function BaseSchema() {
Schema.apply(this,arguments);
this.add({
name: String
});
}
util.inherits(BaseSchema,Schema);
var personSchema = new BaseSchema();
personSchema.methods.speak = function() {
console.log( "my name is %s",this.name );
};
var employeeSchema = new BaseSchema({
title: String
});
employeeSchema.methods.speak = function() {
console.log( "my name is %s and my title is %s",this.name,this.title );
};
var groupSchema = new Schema({
visitor: Schema.Types.Mixed,
note: String,
time: { "type": Date, "default": Date.now }
});
var Person = mongoose.model( 'Person', personSchema, null ),
Employee = Person.discriminator( 'Employee', employeeSchema, null ),
Group = mongoose.model( 'Group', groupSchema );
async.waterfall(
[
// Clean data
function(callback) {
async.each([Person,Group],function(model,callback) {
model.remove(callback);
},callback);
},
// Add a person
function(callback) {
var person = new Person({ "name": "Bob" });
callback(null,person);
},
// Add an employee
function(person,callback) {
var employee = new Employee({ "name": "Sarah", "title": "Manager" });
callback(null,person,employee);
},
// Add person to group
function(person,employee,callback) {
var group = new Group({
visitor: person
});
group.save(function(err) {
callback(err,employee);
});
},
// Add employee to group
function(employee,callback) {
var group = new Group({
visitor: employee
});
group.save(function(err) {
callback(err);
});
},
// Get groups populated
function(callback) {
Group.find().exec(function(err,group) {
console.dir(group);
group.forEach(function(member) {
member.visitor = (member.visitor.hasOwnProperty("__t"))
? mongoose.model(member.visitor.__t)(member.visitor)
: Person(member.visitor);
member.visitor.speak();
});
callback(err);
});
}
],
function(err) {
if (err) throw err;
mongoose.disconnect();
}
);
这与上面的输出相同,创建的对象保留了方便的“鉴别器”信息。所以你可以再次利用之前提到的那么多。
关于node.js - 具有不同对象方法的 Mongoose 多类型模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32033561/
我正在学习构建单页应用程序 (SPA) 所需的所有技术。总而言之,我想将我的应用程序实现为单独的层,其中前端仅使用 API Web 服务(json 通过 socket.io)与后端通信。前端基本上是
当我看到存储在我的数据库中的日期时。 这是 正常 。日期和时间就是这样。 但是当我运行 get 请求来获取数据时。 此格式与存储在数据库 中的格式不同。为什么会发生这种情况? 最佳答案 我认为您可以将
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在尝试使用backbone.js 实现一些代码 和 hogan.js (http://twitter.github.com/hogan.js/) Hogan.js was developed ag
我正在使用 Backbone.js、Node.js 和 Express.js 制作一个 Web 应用程序,并且想要添加用户功能(登录、注销、配置文件、显示内容与该用户相关)。我打算使用 Passpor
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 8 年前。 Improve this ques
我尝试在 NodeJS 中加载数据,然后将其传递给 ExpressJS 以在浏览器中呈现 d3 图表。 我知道我可以通过这种方式加载数据 - https://github.com/mbostock/q
在 node.js 中,我似乎遇到了相同的 3 个文件名来描述应用程序的主要入口点: 使用 express-generator 包时,会创建一个 app.js 文件作为生成应用的主要入口点。 通过 n
最近,我有机会观看了 john papa 关于构建单页应用程序的精彩类(class)。我会喜欢的。它涉及服务器端和客户端应用程序的方方面面。 我更喜欢客户端。在他的实现过程中,papa先生在客户端有类
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我是一个图形新手,需要帮助了解各种 javascript 2D 库的功能。 . . 我从 Pixi.js 中得到了什么,而我没有从 Konva 等基于 Canvas 的库中得到什么? 我从 Konva
我正在尝试将一些 LESS 代码(通过 ember-cli-less)构建到 CSS 文件中。 1) https://almsaeedstudio.com/ AdminLTE LESS 文件2) Bo
尝试查看 Express Passport 中所有登录用户的所有 session ,并希望能够查看当前登录的用户。最好和最快的方法是什么? 我在想也许我可以在登录时执行此操作并将用户模型数据库“在线”
我有一个 React 应用程序,但我需要在组件加载完成后运行一些客户端 js。一旦渲染函数完成并加载,运行与 DOM 交互的 js 的最佳方式是什么,例如 $('div').mixItUp() 。对
请告诉我如何使用bodyparser.raw()将文件上传到express.js服务器 客户端 // ... onFilePicked(file) { const url = 'upload/a
我正在尝试从 Grunt 迁移到 Gulp。这个项目在 Grunt 下运行得很好,所以我一定是在 Gulp 中做错了什么。 除脚本外,所有其他任务均有效。我现在厌倦了添加和注释部分。 我不断收到与意外
我正在尝试更改我的网站名称。找不到可以设置标题或应用程序名称的位置。 最佳答案 您可以在 config/ 目录中创建任何文件,例如 config/app.js 包含如下内容: module.expor
经过多年的服务器端 PHP/MySQL 开发,我正在尝试探索用于构建现代 Web 应用程序的新技术。 我正在尝试对所有 JavaScript 内容进行排序,如果我理解得很好,一个有效的解决方案可以是服
我是 Nodejs 的新手。我在 route 目录中有一个 app.js 和一个 index.js。我有一个 app.use(multer....)。我还定义了 app.post('filter-re
我正在使用 angular-seed用于构建我的应用程序的模板。最初,我将所有 JavaScript 代码放入一个文件 main.js。该文件包含我的模块声明、 Controller 、指令、过滤器和
我是一名优秀的程序员,十分优秀!