这更像是"内部运作"未定问题:
noSQL数据库如何不支持*A*CID(意味着它们无法在单个事务中更新/插入然后回滚多个对象的数据) - 更新二级索引?
我的理解是 - 为了使二级索引保持同步(否则它将变得陈旧) - 这必须在同一事务中发生.
此外,如果索引可能驻留在与数据不同的主机上 - 那么需要存在分布式锁和/或两阶段提交以使这种更新原子地工作.
但是,如果这些数据库不支持多对象事务(这意味着它们不对多个主机上的数据进行两阶段提交),它们使用什么方法来保证驻留在B树结构中的二级索引与数据不陈旧?
如果文档存在,如何进行rethinkdb原子更新,否则插入?
我想做的事情如下:
var tab = r.db('agflow').table('test');
r.expr([{id: 1, n: 0, x: 11}, {id: 2, n: 0, x: 12}]).forEach(function(row){
var _id = row('id');
return r.branch(
tab.get(_id).eq(null), // 1
tab.insert(row), // 2
tab.get(_id).update(function(row2){return {n: row2('n').add(row('n'))}}) // 3
)})
Run Code Online (Sandbox Code Playgroud)
然而,这不是完全原子的,因为在我们检查文档是否存在(1)和插入它(2)之间,某些其他线程可能会插入它.
如何使这个查询原子?
我开始使用Aurelia,RethinkDB和Socket.IO的简单TODO应用程序.我似乎在重新渲染或重新评估通过Socket.IO更改的对象时遇到问题.所以基本上,一切都在第一个浏览器上运行良好但在第二个浏览器中没有重新渲染,而在控制台中显示对象确实显示了我的对象的差异.问题仅在于更新对象时,它完全适用于从待办事项数组创建/删除对象.
HTML
<ul>
<li repeat.for="item of items">
<div show.bind="!item.isEditing">
<input type="checkbox" checked.two-way="item.completed" click.delegate="toggleComplete(item)" />
<label class="${item.completed ? 'done': ''} ${item.archived ? 'archived' : ''}" click.delegate="$parent.editBegin(item)">
${item.title}
</label>
<a href="#" click.delegate="$parent.deleteItem(item, $event)"><i class="glyphicon glyphicon-trash"></i></a>
</div>
<div show.bind="item.isEditing">
<form submit.delegate="$parent.editEnd(item)">
<input type="text" value.bind="item.title" blur.delegate="$parent.editEnd(item)" />
</form>
</div>
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
带有RethinkDB更改源的NodeJS
// attach a RethinkDB changefeeds to watch any changes
r.table(config.table)
.changes()
.run()
.then(function(cursor) {
//cursor.each(console.log);
cursor.each(function(err, item) {
if (!!item && !!item.new_val && item.old_val == null) {
io.sockets.emit("todo_create", item.new_val);
}else if (!!item …Run Code Online (Sandbox Code Playgroud) 我正在使用RethinkDB构建一个应用程序,我即将切换到使用更改源.但我正面临建筑选择,我想得到一些建议.
我的应用程序当前从用户登录的几个表中加载所有用户数据(将所有用户数据发送到前端),然后处理来自前端的请求,更改数据库,准备并向用户发送更改的项目.我想把它换成改变饲料.我看待它的方式,我有两个选择:
getAll带有辅助索引的数据).保持与当前登录用户一样多的更改源.用户注销时关闭它们.解决方案#1有一个很大的缺点:RethinkDB更改源没有时间(或版本号)的概念,例如Kafka.这意味着没有办法a)加载初始数据,b)获得自初始加载以来发生的变化.有一个时间窗口可能会丢失更改:在初始数据加载(a)和更改源设置的时刻(b)之间.我觉得这很令人担忧.
解决方案#2似乎更好,因为includeInitial可以用来获取初始数据,然后不间断地获得后续更改.我必须处理初始加载性能(加载所有数据的单个转储比处理数千次更新更快),但它似乎更"正确".但是缩放呢?我计划每个服务器处理多达1k个用户--RethinkDB准备处理数千个更改源,每个都是一个getAll查询?这些改变饲料的实际活动将非常低,这只是我担心的数字.
RethinkDB手册对更改进度缩放有点简洁,说:
变更进展在扩展时表现良好,尽管它们与每次写入时具有开放式馈送连接的服务器数量成比例地创建额外的集群内消息.
解决方案#2创建了更多的订阅源,但是两个解决方案的开放订阅源连接的服务器数量实际上是相同的.并且"改变饲料表现良好,因为它们规模"还不足以继续:-)
我也有兴趣知道处理服务器重启/升级和断开连接的推荐做法.我看到它的方式,如果RethinkDB发生任何事情,客户端必须includeInitial在重新连接后执行完整数据加载(使用),因为无法知道在停机期间丢失了哪些更改.那是人们做的吗?
我正在构建我的网络应用程序的后端; 它将作为前端的API,它将用Python编写(确切地说是Flask).
在做了一些关于设计和实现的决定之后,我进入了数据库部分.我开始考虑NoSQL数据存储是否比传统的SQL数据库更适合我的项目.以下是一个基本的功能描述,应该由数据库处理,然后我可以提出一个关于我应该选择哪种类型的存储的优缺点列表.最后说一下为什么我考虑过RethinkDB而不是其他NoSQL数据存储.
API的基本功能
API包含只有少数车型:Artist,Song,Suggestion,User和UserArtists.
我希望能够添加User一些关联数据并将其链接Artist到它.我想根据请求添加Songs Artist,并生成一个Suggestionfor User,其中包含一个Artist和一个Song.
也许最重要的部分之一是Artists将定期链接到Users(并且Artists也可以从系统中删除 - 因此也可以从s中删除User- 如果它们不满足某些标准).Songs也将动态添加到Artists.所有这些意味着Users没有固定的Artists组,也没有Artist固定的Songs组 - 它们将不断更新.
优点
对于NoSQL:
Artist都有FacebookID或SongSoundcloudID;Songs 的数量,但特别是Suggestions会提高很多,因此NoSQL会在这里做得更好;对于SQL:
缺点
对于NoSQL …
我testdouble在node.js项目中用于存根调用.这个特殊的功能是包装一个promise并then在函数本身内有多个调用.
function getUser (rethink, username) {
return new Promise((resolve, reject) => {
let r = database.connect();
r.then(conn => database.table(tablename).filter({username}))
.then(data => resolve(data))
.error(err => reject(err));
});
}
Run Code Online (Sandbox Code Playgroud)
所以我想确定是否根据错误条件正确处理resolve和reject处理.假设我需要验证一些自定义逻辑.
为了我的考试
import getUser from './user';
import td from 'testdouble';
test(t => {
const db = td.object();
const connect = td.function();
td.when(connect('options')).thenResolve();
const result = getUser(db, 'testuser');
t.verify(result);
}
Run Code Online (Sandbox Code Playgroud)
问题是connect的结果需要是一个promise,所以我使用一个值来解析,该值需要是另一个解析或拒绝的promise.
与之相关的database.connect()是不是承诺的结果.
TypeError: Cannot read property 'then' of undefined
Run Code Online (Sandbox Code Playgroud)
任何人都可以成功使用Test Double来阻止这种类型的通话吗?
我想运行一个迭代生成器类的函数.只要Ratchet连接处于活动状态,发电机功能就会运行.我需要做的就是在run执行方法后实现这一点:
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;
require dirname(__DIR__) . '/xxx/vendor/autoload.php';
$server = IoServer::factory(
new HttpServer(
new WsServer(
new Chat()
)
),
8180,
'0.0.0.0'
);
$server->run();
Run Code Online (Sandbox Code Playgroud)
这是我在服务器启动后需要运行的方法:
function generatorFunction()
{
$products = r\table("tableOne")->changes()->run($conn);
foreach ($products as $product) {
yield $product['new_val'];
}
}
Run Code Online (Sandbox Code Playgroud)
以前我之前正在调用这个函数$server->run():
for ( $gen = generatorFunction(); $gen->valid(); $gen->next()) {
var_dump($gen->current());
}
$server->run();
Run Code Online (Sandbox Code Playgroud)
但这不允许客户端建立与Ratchet服务器的连接.我怀疑它永远不会$server->run()被生成,因为生成器类正在被迭代.
所以现在,我想首先启动服务器,然后调用这个生成器方法,以便它可以继续监听更改rethinkdb.
我怎么做?
尝试使用此示例连接ID数组:https://github.com/rethinkdb/rethinkdb/issues/1533#issuecomment-26112118
存储表格片段
{
"storeID": "80362c86-94cc-4be3-b2b0-2607901804dd",
"locations": [
"5fa96762-f0a9-41f2-a6c1-1335185f193d",
"80362c86-94cc-4be3-b2b0-2607901804dd"
]
}
Run Code Online (Sandbox Code Playgroud)
位置表格代码段
{
"lat": 125.231345,
"lng": 44.23123,
"id": "80362c86-94cc-4be3-b2b0-2607901804dd"
}
Run Code Online (Sandbox Code Playgroud)
我想选择商店并加入他们的商店位置.
来自ReThinkDB贡献者的原始示例:
r.table("blog_posts")
.concat_map(lambda x: x["comment_ids"].map(lambda y: x.merge("comment_id" : y)))
.eq_join("comment_id", r.table("comments"))
Run Code Online (Sandbox Code Playgroud)
我试图转换为JS
r.table("stores")
.concatMap((function(x){
return x("locations").map((function(y){
return x("locations").add(y);
}))
}))
.eqJoin("locations", r.table("locations"))
Run Code Online (Sandbox Code Playgroud)
结果
RqlRuntimeError: Expected type ARRAY but found STRING
我想列出两个时间戳之间id = 1的记录,最后根据时间戳排序.
Mysql查询的东西:
Select * from test
where (timestamp between 100099323 AND 1423699323) AND id=1
order by timestamp
Run Code Online (Sandbox Code Playgroud)
重新思考数据库中有超过500万个文档.
我尝试使用索引进行简单的mysql查询:
Select * from test where id=1 order by timestamp
Run Code Online (Sandbox Code Playgroud)
和Rethinkdb查询是:
r.table('test').getAll(1, {index: 'id'}).orderBy({index: 'timestamp'})
Run Code Online (Sandbox Code Playgroud)
但我得到错误:
RqlRuntimeError: Indexed order_by can only be performed on a TABLE or
TABLE_SLICE in:
r.table("test").getAll(1, {index: "id"}).orderBy({index: "timestamp"})
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
有什么建议吗?
如何轻松复制生产数据库(mydb)以创建开发数据库(mydb-dev)?
该rethinkdb restore命令似乎没有选项来指定输出数据库的名称.它只能选择我想从转储中恢复哪个数据库.我正在使用rethinkdb 1.16.3
rethinkdb ×10
javascript ×2
acid ×1
aurelia ×1
database ×1
indexing ×1
mongodb ×1
node.js ×1
nosql ×1
performance ×1
php ×1
python ×1
ratchet ×1
sockets ×1
sql ×1
test-double ×1
testdoublejs ×1
transactions ×1