- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我是 Mongodb 的新手,听说 Mongodb 非常适合海量读写操作。嵌入式文档是实现这一目标的功能之一。但我不确定这是否也是性能问题的原因。书籍文档示例:
{
"_id": 1,
"Authors": [
{
"Email": "email",
"Name": "name"
}
],
"Title": "title",
...
}
如果一个作者有几千本书,他的邮箱需要更新,我需要写一些查询可以
这些操作看起来效率不高。但这种更新无处不在,相信开发者已经考虑到了这一点。那么,我哪里做错了?
最佳答案
您当前的嵌入式模式设计有其优点,其中之一就是数据局部性。由于 MongoDB 在磁盘上连续存储数据,将您需要的所有数据放在一个文档中可确保旋转磁盘花费更少的时间来寻找磁盘上的特定位置。
如果您的应用程序经常访问 books
信息以及 Authors
数据,那么您几乎肯定会希望采用嵌入式路线。嵌入式文档的另一个优点是写入数据的原子性和隔离性。
为了说明这一点,假设您希望一位作者的所有书籍都更新他的电子邮件字段,这可以通过一个(原子)操作完成,这不是 MongoDB 的性能问题:
db.books.updateMany(
{ "Authors.name": "foo" },
{
"$set": { "Authors.$.email": "new@email.com" }
}
);
或早期的 MongoDB 版本:
db.books.update(
{ "Authors.name": "foo" },
{
"$set": { "Authors.$.email": "new@email.com" }
},
{ "multi": true }
)
在上面,您使用了 positional $
operator它通过识别数组中要更新的元素而不显式指定数组中元素的位置来促进对包含嵌入式文档的数组的更新。与 dot notation 一起使用在 $
运算符上。
有关 MongoDB 中数据建模的更多详细信息,请阅读文档 Data Modeling Introduction , 特别是 Model One-to-Many Relationships with Embedded Documents .
您可以考虑的另一个设计选项是引用遵循规范化模式的文档。例如:
// db.books schema
{
"_id": 3
"authors": [1, 2, 3] // <-- array of references to the author collection
"title": "foo"
}
// db.authors schema
/*
1
*/
{
"_id": 1,
"name": "foo",
"surname": "bar",
"address": "xxx",
"email": "foo@mail.com"
}
/*
2
*/
{
"_id": 2,
"name": "abc",
"surname": "def",
"address": "xyz",
"email": "abc@mail.com"
}
/*
3
*/
{
"_id": 3,
"name": "alice",
"surname": "bob",
"address": "xyz",
"email": "alice@mail.com"
}
当您拥有非常不可预测的一对多关系时,上述使用文档引用方法的规范化模式也有优势。如果每个给定的书实体有成百上千个作者文档,那么嵌入在空间限制方面会遇到很多挫折,因为文档越大,它使用的 RAM 就越多,而 MongoDB 文档的硬大小限制为 16MB。
对于规范化模式的查询,可以考虑使用聚合框架的 $lookup
运算符,它对同一数据库中的 authors
集合执行左外连接,以从 books
集合中过滤文档进行处理。
因此,我相信您当前的模式是比创建单独的 authors
集合更好的方法,因为单独的集合需要更多的工作,即查找一本书 + 它的作者是两个查询,需要额外的工作,而上述模式嵌入文档简单快捷(单次搜索)。插入和更新没有太大区别。因此,如果您需要选择单个文档、需要对查询进行更多控制或拥有大量文档,则单独的集合是很好的选择。当您想要整个文档时,嵌入式文档也很好,带有 $slice
的文档 嵌入的作者
,或者根本没有作者
。
一般的经验法则是,如果您的应用程序的查询模式众所周知并且数据往往只能以一种方式访问,那么嵌入式方法会很有效。如果您的应用程序以多种方式查询数据,或者您无法预测数据查询模式,则更规范化的文档引用模型将适用于这种情况。
引用:
关于mongodb - 更新 Mongodb 中的嵌入文档 : Performance issue?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40157403/
我查看了网站上的一些问题,但还没有完全弄清楚我做错了什么。我有一些这样的代码: var mongoose = require('mongoose'), db = mongoose.connect('m
基本上,根据 this bl.ocks,我试图在开始新序列之前让所有 block 都变为 0。我认为我需要的是以下顺序: 更新为0 退出到0 更新随机数 输入新号码 我尝试通过添加以下代码块来遵循上述
我试图通过使用随机数在循环中设置 JSlider 位置来模拟“赛马”的投注结果。我的问题是,当然,我无法在线程执行时更新 GUI,因此我的 JSlider 似乎没有在竞赛,它们从头到尾都在运行。我尝试
该功能非常简单: 变量:$table是正在更新的表$fields 是表中的字段,$values 从帖子生成并放入 $values 数组中而$where是表的索引字段的id值$indxfldnm 是索引
让我们想象一个环境:有一个数据库客户端和一个数据库服务器。数据库客户端可以是 Java 程序或其他程序等;数据库服务器可以是mysql、oracle等。 需求是在数据库服务器上的一个表中插入大量记录。
在我当前的应用程序中,我正在制作一个菜单结构,它可以递归地创建自己的子菜单。然而,由于这个原因,我发现很难也允许某种重新排序方法。大多数应用程序可能只是通过“排序”列进行排序,但是在这种情况下,尽管这
Provisioning Profile 有 key , key 链依赖于它。我想知道 key 什么时候会改变。 Key will change after renew Provisioning Pr
截至目前,我在\server\publications.js 中有我的 MongoDB“选择”,例如: Meteor.publish("jobLocations", function () { r
我读到 UI 应该始终在主线程上更新。但是,当谈到实现这些更新的首选方法时,我有点困惑。 我有各种函数可以执行一些条件检查,然后使用结果来确定如何更新 UI。我的问题是整个函数应该在主线程上运行吗?应
我在代理后面,我无法构建 Docker 镜像。 我试过 FROM ubuntu , FROM centos和 FROM alpine ,但是 apt-get update/yum update/apk
我构建了一个 Java 应用程序,它向外部授权客户端公开网络服务。 Web 服务使用带有证书身份验证的 WS-security。基本上我们充当自定义证书颁发机构 - 我们在我们的服务器上维护一个 ja
因此,我有时会在上传新版本时使用 app_offline.htm 使应用程序离线。 但是,当我上传较大的 dll 时,我收到黄色错误屏幕,指出无法加载 dll。 这似乎与我对 app_offline.
我刚刚下载了 VS Apache Cordova Tools Update 5,但遇到了 Node 和 NPM 的问题。我使用默认的空白 cordova 项目进行测试。 版本 如果我在 VS 项目中对
所以我有一个使用传单库实例化的 map 对象。 map 实例在单独的模板中创建并以这种方式路由:- var app = angular.module('myApp', ['ui', 'ngResour
我使用较早的 Java 6 u 3 获得的帧速率是新版本的两倍。很奇怪。谁能解释一下? 在 Core 2 Duo 1.83ghz 上,集成视频(仅使用一个内核)- 1500(较旧的 java)与 70
我正在使用 angular 1.2 ng-repeat 创建的 div 也包含 ng-click 点击时 ng-click 更新 $scope $scope 中的变化反射(reflect)在使用 $a
这些方法有什么区别 public final void moveCamera(CameraUpdate更新)和public final void animateCamera (CameraUpdate
我尝试了另一篇文章中某人评论中关于如何将树更改为列表的建议。但是,我在某处(或某物)有未声明的变量,所以我列表中的值是 [_G667, _G673, _G679],而不是 [5, 2, 6],这是正确
实现以下场景的最佳方法是什么? 我需要从java应用程序调用/查询包含数百万条记录的数据库表。然后,对于表中的每条记录,我的应用程序应该调用第三方 API 并获取状态字段作为响应。然后我的应用程序应该
只是在编写一些与 java 图形相关的代码,这是我今天的讲座中的非常简单的示例。不管怎样,互联网似乎说更新不会被系统触发器调用,例如调整框架大小等。在这个例子中,更新是由这样的触发器调用的(因此当我只
我是一名优秀的程序员,十分优秀!