情况如下:
我们有一系列用户共享一些文档。他们可以共享的文档可能会在一天内发生变化,文档本身也可能发生变化(更改和删除)。用户可以更改文档中的一些信息
例如
用户|文件
A | X
A | ÿ
A | ž
B | X
B | ž
C |是的
可能的组:A + C,A + B
CouchDB上的服务器是带有此数据的SQL Server数据库的副本,ETL负责管理CouchDB上的更改。但是,CouchDB数据库通过PouchDB在每个用户手机上复制。
目标:
相应地复制更改和删除。
我们尝试了什么:
1)我们认为我们使用可以访问它的用户列表来构建我们的文档。每个文档都有一个"用户"数组,然后设计文档中的过滤器将负责复制到客户端。遗憾的是,_changes Feed中不存在未通过过滤器的文档删除和文档更改(例如,用户已从阵列中删除),因此无法在客户端上进行相应的复制。
2)每个用户的数据库。这是不可能的,因为用户需要看到彼此在文档上工作(他们共享它们)
3)每组用户的数据库。与第一个解决方案几乎相同的问题,但更糟。事实上:
- 用户组可以更改,不再存在:如何反映客户端?
- 文档可以转移到新组:它必须从头开始重新下载。这大大增加了下载量
- 同一份文件可以在多个组中! (见上面的例子)
- 每个客户每次登录并复制多个数据库时都必须知道她在哪个组中。然后在回程中,你必须知道文件存在于哪个数据库
这种情况有配方吗?我错过了一个明显的解决方案吗?
案例1的部分解决方案:
localDB.sync(remoteDB, {
live: true,
retry: true,
filter: 'app/by_user',
query_params: { "agente": agent }
})
.on('paused', function(info){
console.log("paused");
localDB.allDocs().then(function(docs){
console.log("allDocs");
docs.rows.forEach(function(row){
console.log(row);
remoteDB.get(row.id)
.then(function(doc){
if(doc.Agents.indexOf(agent) < 0){
localDB.remove(doc);
}
});
});
});
})
.on('change', function(result){
console.log("change!");
result.change.docs.forEach(function(change) {
if(!change.deleted){
$rootScope.$apply(function(){
$rootScope.$broadcast('upsert', change);
});
}
});
});
每个remove()给我一个409(冲突),这是理所当然的。有没有办法告诉Pouch&#34;不再认为这是可复制的,只是从我的数据库中删除它?&#34;
答案 0 :(得分:2)
(3)对我来说似乎是最简单的解决方案,即每个角色的数据库&#34;溶液
我认为您的困难源于尝试管理文档内部的权限(然后使用过滤复制)。当你这样做时,你基本上是在试图在文档中反映CouchDB的权限系统,这会引起令人头疼的问题。
为什么不为每个角色创建一个数据库,并使用普通的_users
数据库为用户分配角色?如果角色发生变化,则用户将失去或获得对一组文档的访问权限。您需要有服务器端点来处理角色改组,或者您需要设置单独的&#34; admin&#34;具有特殊权限的数据库,用户可以在其中更改角色。
然后在客户端,您可以从多个CouchDB数据库复制到单个PouchDB(然后自己整理结果),或者复制到单个PouchDB中(如果您需要双向同步,可能是个坏主意)。显然,您需要一个初始步骤来确定用户可以访问哪些数据库,但这是我认为的一个小缺点。
然后,如果用户失去对文档的访问权限,他们只会在复制期间获得正常的401错误(在实时复制期间将显示在'denied'
事件中)。不需要ddocs或过滤复制 - 更简单!
答案 1 :(得分:0)
我们得出结论:
1)我们的用例可能不是CouchDB的好处
2)我们重视我们的心理健康。经过近一个月的努力解决这个问题,我们宁愿尝试也不会失败
3)文件相对便宜,所以即使他们留在用户的手机上也不会造成任何重大困扰。如果数据过多,他们可以简单地清除数据并开始新的
解决方案:
1)保持架构与点1相同
2)每次“暂停”事件触发器将本地文档与远程文档进行比较后,如果远程文档未通过过滤器,则将其从UI中删除。如果有办法删除本地文档,我们将非常有兴趣升级到该逻辑。
答案 2 :(得分:0)
1)对我来说仍然是最简单的方法..
我不太了解PouchDB,但在简单的CouchDB中,通过使用您自己的自定义DELETE函数扩展已删除文档的属性,可以解决已删除文档的变通方法。
我的意思是.. 删除就像是将 _deleted 属性设置为 true 的更新。
因此,不是直接删除文档,而是使用文档中的常规CouchDB crud DELETE,可以创建更新函数,如下所示:
function(doc,req){
// optional acls for deleting doc.. doc is owned by req.userCtx.name
// doc.users are users already granted to work with this doc
return [{
"_id" : doc._id,
"_rev": doc._rev,
"_deleted":true,
"users": doc.users
},"Ok doc deleted"];
}
此外,使用文档重写规则,即使提交HTTP DELETE请求(不仅仅是在PUT或POST上),最终也可以调用此更新函数。这样,删除行为对客户端变得完全透明< / strong> ...并且您以对您的用例更有用的方式删除。
Smileupps Chatty couchapp tutorial app使用此方法:在 user / drop.js , profile / drop中执行不同文档类型的扩展删除。 js , chat / drop.js 文件