我错过了什么吗?与传统数据库相比,为什么在 ORM 中需要更多的努力来同步关系。以下面的例子。
var UserSchema = new Schema({
username: {type: String, required: true, index:{unique:true}},
password: {type: String, required: true},
events: [{type: Schema.Types.ObjectId, ref:'Event'}]
});
var EventSchema = new Schema({
_creator: {type:Schema.Types.ObjectId, ref: 'User'},
post: {type: String, required: true}
});
UserSchema 有许多事件,其中事件模式属于一个用户,也就是创建者。
.delete(function(req, res){
Event.remove({
_id:req.params.event_id
},function(err,response){
if(err)
res.send(err);
res.json({message:'Successfully Deleted'});
});
});
如果我创建一个事件并将用户对象添加为创建者,它会成功加入表,但如果我删除该事件。事件不再显示,但 ID 仍显示在用户查询下。
下面是删除属于用户的事件后我的用户查询的样子
[
{
"_id": "5831be814f8df40646fed954",
"password": "$2a$10$MNbwpj0qi9.rhEPmCHe5mOc8crrEo/CwbxVSbjjLSw28GdcQ0O6Um",
"username": "klaus",
"__v": 1,
"events": [
"5831c216a3d6810692bdf381"
]
}
]
我将如何从用户架构中删除该 ID?不将 Events Schema 与 Users Schema 链接起来会更好吗?为什么这是一件令人头疼的事,为什么这就是 future ?
最佳答案
这不是 ORM,没有连接也没有表。您正在尝试将 Mongo 当作关系数据库来使用,但事实并非如此。
回答您的问题“为什么这是一件令人头疼的事情,为什么这是 future ?” - 除非您将 Mongo 识别为文档存储并照此使用它,否则您将永远感到失望。
现在,一些背景。在关系数据库中,你可以有外键、约束和触发器,它们可以确保你不能在另一个关系中引用元组时删除它,或者你可以删除它但操作级联并删除现在指向一个元组的引用不存在的键并导致数据库不一致。这通常也是在一次事务中完成的,因此您可以确保没有人会看到不一致的数据 View 。
Mongo 没有这样的保证。有validations但那些可以是bypassed .
当您存储对另一个文档的引用时,它只是一个字符串或一个 ObjectId 实例,不必存在于数据库中的任何地方。 “引用提供了比嵌入更多的灵 active 。但是,客户端应用程序必须发出后续查询来解析引用。换句话说,规范化数据模型可能需要更多往返服务器。” (参见 Normalized Data Models)换句话说,不仅关系的有效性没有强制执行,实际的“加入”发生在客户端,而不是在数据库中,在单独的查询中(可能存在竞争条件)。
此外,您没有事务,因此不可能在一个原子操作中删除文档和对它的所有引用。但即使有可能,Mongo 中仍然没有模式,所以只要您将 ObjectId 作为某个字段的值,Mongo 就不知道它应该引用哪个集合,所以它甚至不知道去哪里寻找。
这意味着您需要在删除可能在另一个文档中引用的数据后手动清理。但是由于数据库不会告诉您要删除的文档的 ObjectId 可能存储在哪里,因此您有责任了解这一点并确保自己保持数据库的一致性。
现在,对于模式。 Mongo 中确实没有模式的概念。 Mongoose 中有模式,但 Mongo 中没有。 “MongoDB 中的数据具有灵活的架构。集合不强制执行文档结构。” (参见 Data Modeling)拥有“灵活模式”意味着根本没有模式。实际上,模式仅存在于 Mongoose 的客户端中。您可以拥有一个很好的 Mongoose 模式,但如果您有多个应用程序连接到同一个数据库(或者甚至是同一应用程序的两个版本),那么这些应用程序可能具有不一致的模式,并可能悄悄地破坏您的数据库。
综合考虑,我建议仅当您不需要保证一致性、事务、外键、连接、强制模式和您在使用其他数据库时可能熟悉的其他功能时才使用 Mongo,或者否则就像您描述的那样,它将永远是一种痛苦。
关于node.js - Mongoose 和 MongoDB,关系不同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40723019/
我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年
我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.
RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)
A/ctohttp://wiki.nginx.org/CoreModule#usermaster进程曾经以root用户运行,是否可以以不同的用户运行nginxmaster进程? 最佳答案 只需以非root身份运行init脚本(即/etc/init.d/nginxstart),就可以用不同的用户运行nginxmaster进程。如果这真的是你想要做的,你将需要确保日志和pid目录(通常是/var/log/nginx&/var/run/nginx.pid)对该用户是可写的,并且您所有的listen调用都是针对大于1024的端口(因为绑定(
有没有办法在sinatra的beforedoblock中停止执行并返回不同的值?beforedo#codeishere#Iwouldliketo'return"Message"'#Iwouldlike"/home"tonotgetcalled.end//restofthecodeget'/home'doend 最佳答案 beforedohalt401,{'Content-Type'=>'text/plain'},'Message!'end如果你愿意,你可以只指定状态,这里有状态、标题和正文的例子
我想用sunspot重现以下原始solr查询q=exact_term_text:fooORterm_textv:foo*ORalternate_text:bar*但我无法通过标准的太阳黑子界面理解这是否可能以及如何实现,因为看起来:fulltext方法似乎不接受多个文本/搜索字段参数我不知道将什么参数作为第一个参数传递给fulltext,就好像我通过了"foo"或"bar"结果不匹配如果我传递一个空参数,我得到一个q=*:*范围过滤器(例如with(:term).starting_with('foo*')(顾名思义)作为过滤器查询应用,因此不参与评分。似乎可以手动编写字符串(或者可能使
我想合并多个事件记录关系例如,apple_companies=Company.where("namelike?","%apple%")banana_companies=Company.where("namelike?","%banana%")我想结合这两个关系。不是合并,合并是apple_companies.merge(banana_companies)=>Company.where("namelike?andnamelike?","%apple%","%banana%")我要Company.where("名字像?还是名字像?","%apple%","%banana%")之后,我会写代
我从ui中得到日期范围为-approved_between"=>"2013-03-17-2013-03-18"我需要拆分此approved_start_date="2013-03-17"和approved_end_date="2013-03-18"...我希望使用它在mysql中查询,因为mysql中的日期格式是created_at:2012-07-2810:35:01.我正在做的是:approved=approved_between.split("")approved_start_date=approved[0]approved_end_date=approved[2]很确定这不是处