【问题标题】:How to build "Tagging" support using CouchDB?如何使用 CouchDB 构建“标记”支持?
【发布时间】:2008-10-17 04:57:22
【问题描述】:

我正在使用以下视图函数来迭代数据库中的所有项目(以便找到标签),但我认为如果数据集很大,性能会很差。 还有其他方法吗?

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

【问题讨论】:

    标签: python couchdb tagging document-oriented-db


    【解决方案1】:

    免责声明:我没有对此进行测试,不知道它是否可以表现得更好。

    创建单个烫发视图:

    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 结构会略有不同,但您仍会得到发布日期排序。

    【讨论】:

    • 确实!使用startkey 等将是执行此操作的“正确”方法。
    • 不应该是emit([doc.tags[tag], doc.published], doc)吗?否则,如果我没记错的话,你只会发出索引。
    【解决方案2】:

    您可以按照 Bahadir 的建议定义一个永久视图。但是,在进行这种索引时,不要为每个键输出文档。相反,emit([tag, doc.published], null)。在当前版本中,您必须对每个文档进行单独查找,但 SVN 主干现在支持在查询字符串中指定“include_docs=True”,并且 CouchDB 会自动为您将文档合并到您的视图中,而无需空间开销。

    【讨论】:

      【解决方案3】:

      您的观点非常正确。一个想法列表:

      视图生成是增量的。如果您的读取流量大于写入流量,那么您的视图根本不会引起问题。对此感到担忧的人通常不应该如此。参考框架,如果您在没有更新的情况下将数百条记录转储到视图中,您应该担心。

      发送整个文档会减慢速度。您应该只发出使用视图所必需的内容。

      不确定 val == "%s" 的性能如何,但你不应该想太多。如果有标签数组,您应该发出标签。如果您期望一个包含非字符串的标签数组,那么请忽略它。

      【讨论】:

      • 嗨,保罗,感谢您的积分。临时视图是否也是增量生成的?正如 Jan L. 在另一个线程中提到的那样,临时视图不应在生产中使用。剂量是否意味着我必须为我拥有的每个标签创建永久视图?
      • 森妙,临时视图的问题在于它们是临时的。一旦没有客户端使用它们,它们就会被删除,并且下一个请求需要重建整个视图。
      • 尽量不要将视图视为 SQL 查询。视图通常应设计为回答一类查询而不是特定查询。在您的情况下,您希望所有标签都有一个视图,而不是每个标签都有一个视图。
      • 感谢 Paul,一个标签一个视图,这很有帮助。
      【解决方案4】:
      # Works on CouchDB 0.8.0
      from couchdb import Server # http://code.google.com/p/couchdb-python/
      
      byTag = """
      function(doc) {
      if (doc.type == 'post' && doc.tags) {
          doc.tags.forEach(function(tag) {
              emit(tag, doc);
          });
      }
      }
      """
      
      def findPostsByTag(self, tag):
          server = Server("http://localhost:1234")
          db = server['my_table']
          return [row for row in db.query(byTag, key = tag)]
      

      byTag 映射函数返回“key”中每个唯一标签的数据,然后在value 中返回每个带有该标签的帖子,因此当您抓取 key =“mytag”时,它将检索所有带有标签的帖子“我的标签”。

      我已经针对大约 10 个条目对其进行了测试,每次查询似乎需要大约 0.0025 秒,不确定它对大型数据集的效率如何..

      【讨论】:

      • 如果您按照 Bahadır 的建议使用永久视图,效率会更高。
      猜你喜欢
      • 1970-01-01
      • 2019-07-06
      • 2011-02-22
      • 1970-01-01
      • 2020-09-11
      • 1970-01-01
      • 2015-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多