如何在CouchDB中构建“标签”支持?
我正在使用以下的视图函数来遍历数据库中的所有项目(目的是为了找到一个标签),但是我觉得如果数据量很大,性能会很差。有没有其他更好的方法?
def by_tag(tag):
return '''
function(doc) {
if (doc.tags.length > 0) {
for (var tag in doc.tags) {
if (doc.tags[tag] == "%s") {
emit(doc.published, doc)
}
}
}
};
''' % tag
4 个回答
1
你在处理视图方面的思路是对的。不过,我有一些想法想和你分享:
视图的生成是逐步进行的。如果你读取数据的频率比写入数据的频率高,那么你的视图就不会出现问题。其实,担心这个问题的人大多数是没必要的。简单来说,如果你一次性往视图里放入几百条记录而不更新,那才是需要担心的事情。
一次性发出整个文档会让事情变得慢下来。你应该只发出视图使用所需的内容。
关于val == "%s"的性能我不太确定,但你不需要想得太复杂。如果有一个标签数组,你应该把这些标签发出来。当然,如果你预期这个标签数组里会有非字符串的内容,那就可以忽略这个建议。
3
你可以像Bahadir建议的那样,定义一个永久的视图。不过,在进行这种索引时,不要为每个键输出文档。相反,你应该使用emit([tag, doc.published], null)。在当前的版本中,你需要为每个文档单独查找,但在SVN的最新版本中,你可以在查询字符串中指定“include_docs=True”,这样CouchDB会自动把文档合并到你的视图中,而不会占用额外的空间。
7
免责声明:我没有测试过这个,不知道它是否能表现得更好。
创建一个永久视图:
function(doc) {
for (var tag in doc.tags) {
emit([tag, doc.published], doc)
}
};
然后用以下方式查询: _view/your_view/all?startkey=['your_tag_here']&endkey=['your_tag_here', {}]
得到的JSON结构会稍微不同,但你仍然可以按照发布日期进行排序。