如何在Couchdb map/reduce中按用户查看喜爱的用户文档?
My Couchdb数据库作为主文档类型,类似于:如何在Couchdb map/reduce中按用户查看喜爱的用户文档?,couchdb,mapreduce,Couchdb,Mapreduce,My Couchdb数据库作为主文档类型,类似于: { "_id" : "doc1", "type" : "main_doc", "title" : "the first doc" ... } { "_id" : "fav1", "type" : "favorite", "user_id" : "user1", "doc_id" : "doc1" } { "key" : "user1", "value" : ["doc1", "the firs
{
"_id" : "doc1",
"type" : "main_doc",
"title" : "the first doc"
...
}
{
"_id" : "fav1",
"type" : "favorite",
"user_id" : "user1",
"doc_id" : "doc1"
}
{ "key" : "user1", "value" : ["doc1", "the first doc"] }
还有另一种类型的文档存储用户信息。我希望用户能够将文档标记为收藏夹。不同的用户可以将相同或不同的文档保存为收藏夹。我的想法是引入一个最喜欢的文档来跟踪它,比如:
{
"_id" : "doc1",
"type" : "main_doc",
"title" : "the first doc"
...
}
{
"_id" : "fav1",
"type" : "favorite",
"user_id" : "user1",
"doc_id" : "doc1"
}
{ "key" : "user1", "value" : ["doc1", "the first doc"] }
创建一个以user_id为键的视图很容易,可以获得他们最喜欢的文档id列表。例如:
function(doc) {
if (doc.type == "favorite") {
emit(doc.user_id, doc.doc_id);
}
}
但是,我想列出收藏夹以显示文档中的用户id、文档id和标题。因此,输出如下内容:
{
"_id" : "doc1",
"type" : "main_doc",
"title" : "the first doc"
...
}
{
"_id" : "fav1",
"type" : "favorite",
"user_id" : "user1",
"doc_id" : "doc1"
}
{ "key" : "user1", "value" : ["doc1", "the first doc"] }
在CouchDB 0.11(刚刚发布)中,包含功能。例如:
function(doc) {
if(doc.type == "favorite") {
emit(doc.user_id, {_id: doc.doc_id});
}
}
当您使用include_docs=true
查询视图时,您会看到如下JSON:
// ... normal stuff
rows: [
{
"key":"user1",
"value":{"_id":"doc1"},
"doc": {
"_id" : "doc1",
"type" : "main_doc",
"title" : "the first doc"
// ...
}
},
{
// another doc, etc...
}
]
如果无法在v0.11中使用
include_docs=true
功能,则在为视图/地图发送数据时,必须手头有所有信息
代替传统的“连接”样式,考虑在“代码> MixyODC/<代码>文档中存储一个“最喜欢”用户列表。
{
"_id" : "doc1",
"type" : "main_doc",
"title" : "the first doc",
"favorited_by": ["user1", "user2"]
// ...
}
这样,当视图运行时,您可以基于该文档中的信息发出所有内容
function(doc) {
if(doc.type == "main_doc") {
for (var a in doc.favorited_by) {
emit(doc.favorited_by[a], [doc._id, doc.title]);
}
}
}
这是一个很酷的新特性,但我不想返回整个文档。我只想要一个只有标题的最喜欢的项目列表。如果用户选择查看文档,我只需要整个文档。是的,我理解。当然,我的解决方案也会迫使您升级。但是我不确定如何在没有“模式”重构的情况下实现你想要的。我会考虑重构文档如何被配置来适应这个。有什么建议吗?我会添加另一个答案。如果你可以做一个include_docs,然后指定一个子集的文档字段,你想包括在视图中,那就太酷了。或者在单独的请求中获取文档标题真的不会有太多开销吗?我已经有了另一个输出文档ID和标题的视图。我试图避免再次调用数据库来获取每个收藏夹的文档标题。我可能在这里遇到了可伸缩性问题吗?如果很多用户试图将此文档添加为收藏夹,我可能会遇到很多冲突。是的,你是对的。这是一种取舍,取决于您的预期使用情况。另一个想法是以另一种方式存储它:在用户对象中存储
[“doc\u id”,“doc Title”]
元组。这将需要三次往返(1:获取主文档;2:获取用户文档,3:使用新元组更新用户文档),但是您可能已经在必要的时候准备好了所有这些文档。与通过联接样式文档在读取时进行多个查找相比,我仍然更喜欢这种方式。我希望对最喜欢的查找进行一次读取操作。我还试图避免将文档标题复制到其他文档中,因为如果在实际文档中更新了标题,则复制的标题已过期,或者我需要查找并更新所有将此文档作为收藏夹的用户文档。我现在只需读取视图一次,即可查找用户的收藏夹文档ID。然后,对于每个最喜欢的,我都会用另一本书来查找标题。