2010-03-22 45 views
1

我的CouchDB数据库作为主文档类型,看起来像:如何在Couchdb map/reduce中获得用户喜爱的用户文档视图?

{ 
    "_id" : "doc1", 
    "type" : "main_doc", 
    "title" : "the first doc" 
    ... 
} 

有存储用户信息的文件另一种类型。我希望用户能够将文档标记为收藏夹。不同的用户可以将相同或不同的文档保存为收藏夹。我的想法是引进了最喜欢的文档跟踪此类似:

{ 
    "_id" : "fav1", 
    "type" : "favorite", 
    "user_id" : "user1", 
    "doc_id" : "doc1" 
} 

这是很容易创建USER_ID为重点,以获得自己喜欢的文档ID列表的视图。例如:

function(doc) { 
    if (doc.type == "favorite") { 
     emit(doc.user_id, doc.doc_id); 
    } 
} 

但是我想列出收藏夹以显示文档中的user_id,doc_id和标题。所以输出是这样的:

{ "key" : "user1", "value" : ["doc1", "the first doc"] } 
+0

或者在单独的请求中获取文档标题真的没有多少开销?我已有另一个输出文档ID和标题的视图。我试图避免再次调用数据库来获取每个喜爱的文档标题。 – 2010-03-23 12:21:14

回答

2

在CouchDB中0.11(只是最近发布),该功能include_docs=trueallows you to look up any document in your view row。例如:

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... 
    } 
] 
+0

这是一个很酷的新功能,但我不想返回整个文档。我只想要一个只有标题的喜欢项目列表。如果用户选择查看文档,我只需要整个文档。 – 2010-03-23 12:03:01

+0

是的,我明白。当然,我的解决方案也会迫使你升级。但我不确定如何在没有“模式”重构的情况下完成自己想要的任务。 – JasonSmith 2010-03-23 16:55:19

+0

我会考虑重构文档如何安排来适应这种情况。有什么建议么? – 2010-03-23 21:04:49

0

如果您无法使用include_docs=true功能与v0.11,那么你必须有当你为你的视图/地图发射数据时,所有的信息都将在手边。

而不是传统的“加入”风格,可以考虑在main_doc文档中存储“偏爱”用户列表。

{ 
    "_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]); 
     } 
    } 
} 
+0

我可能不会遇到可伸缩性问题吗?如果很多用户试图将这个文档添加为收藏夹,我可能会遇到很多冲突。 – 2010-03-24 21:27:47

+0

是的,你是对的。这是一种取决于您的预期使用情况的权衡。另一个想法是以另一种方式存储它:在用户对象中存储'[“doc_id”,“文档标题”]元组。这需要三次往返(1:获取主文档; 2:获取用户文档,3:用新元组更新用户文档),但是您可能已经在必要的时间使用所有这些文档。在读取时,通过您的连接样式文档,我仍然希望将这一点与多次查找相比较。 – JasonSmith 2010-03-24 23:20:19

+0

我希望对最喜欢的查找进行单独的读取操作。我还试图避免将文档标题复制到其他文档中,因为如果标题在实际文档中得到更新,则复制的标题已过期,或者需要使用此文档作为最喜欢的文档来查找和更新所有用户文档。 – 2010-03-25 02:01:03

相关问题