如何在CouchDB中构建“标签”支持?

4 投票
4 回答
1880 浏览
提问于 2025-04-11 09:34

我正在使用以下的视图函数来遍历数据库中的所有项目(目的是为了找到一个标签),但是我觉得如果数据量很大,性能会很差。有没有其他更好的方法?

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结构会稍微不同,但你仍然可以按照发布日期进行排序。

撰写回答