【问题标题】:CouchDB map/reduce by any document property at runtime?CouchDB 在运行时通过任何文档属性映射/减少?
【发布时间】:2011-09-23 22:50:07
【问题描述】:

我来自一个 SQL 世界,在这个世界中,查找由多个对象属性(published = TRUE 或 user_id = X)完成,并且任何地方都没有连接(因为 1:1 缓存层)。看来文档数据库很适合我的数据。

我试图弄清楚是否有一种方法可以将一个(或多个)对象属性传递给 CouchDB map/reduce function 以在数据库中查找匹配的文档,而无需为每个对象创建 几十个 视图文档类型。

是否可以在运行时将所需的文档属性键传递给 CouchDB 并让它返回匹配的对象(或匹配分页的对象的计数)?

例如,在一个页面上,我希望所有带有 doc.user_id 的 X 的帖子都是 doc.published。在另一个页面上,我可能想要所有带有 doc.tags[] 且带有“sport”标签的文档。

【问题讨论】:

    标签: couchdb document-database


    【解决方案1】:

    您可以构建一个遍历文档中键的视图,并发出 [propertyName, propertyValue] 的键 - 这样您就可以构建一个包含所有属性/值的单一索引。会很大,不知道如何构建性能,以及磁盘使用情况(可能很糟糕)。

    地图函数看起来像:

    // note - totally untested, my CouchDB fu is rusty
    function(doc) {
      for(prop in doc) {
        emit([prop, doc[prop]], null);
      }
    }
    

    适用于简单属性的基本情况,并且可以扩展为对数组更智能,并为数组中的每个项目发出一个 prop/value 对。这样你就可以处理标签了。

    要对其进行查询,请将 [prop] 设置为视图上的查询键。

    【讨论】:

    • 所以听起来这是个坏主意。这是可能的——但这是个坏主意。太糟糕了,多亏了我的 ORM,我已经很久没有编写 SQL 查询了,以至于我不期待为我查找数据的所有不同方式编写模型方法(或 CouchDB 中的视图)。话又说回来,至少所有查询都列在 _design 文档中,供项目新手使用。
    【解决方案2】:

    基本上没有。

    Couch 和 SQL DB 之类的主要区别在于,在 CouchDB 中进行查询的唯一方法本质上是通过视图/索引。 SQL 中的索引是可选的。它们的存在(主要)是为了提高性能。例如,如果您有一个小型数据库,您的应用程序将在索引为 0 的 SQL 上运行良好。 (可能是唯一约束的一些问题,但这是一个细节。)

    总体而言,SQL 数据库中的部分查询处理器包括简单的索引之外的其他数据访问方法,特别是表扫描、合并连接等。

    Couch 没有查询处理器。它具有用于定义 B-Tree 索引的视图(由 JS 定义)。

    而且,就是这样。这就是沙发的锤子。是个好锤子。它已经在数据处理领域持续了 40 年。

    在 Couch 中创建索引有点昂贵(基于数据量),这就是为什么“临时视图”不受欢迎的原因。而且它们也有维护成本,因此视图需要成为数据库中的一个有意识的设计元素。同时,它们也比普通的 SQL 索引更强大。

    您可以很容易地在 Couch 上添加自己的查询处理,但这对您来说工作量更大。您可以根据最流行或最有选择的标准创建一些选择视图,然后在您自己的代码中按其他标准过滤结果文档。是的,您必须这样做,因此您必须质疑所涉及的努力是否比您认为 Couch 通过 SQL 解决方案为您提供的任何好处(HTTP API、复制、安全、始终一致的数据存储等)更有价值。

    【讨论】:

    • “始终一致的数据存储” - CouchDB 不是最终一致的,这意味着它不可能始终一致,否则就 CAP 定理而言它不​​会高度可用?
    • 如果您在谈论复制和集群,它们是的。我所说的始终一致的意思是,对于 Couch 的单个实例,它是“防崩溃的”。即使系统或服务器崩溃,数据库也始终处于一致、可用的状态。重新启动后,数据库立即一致且可用。
    【解决方案3】:

    我遇到了类似的问题,并使用 CouchDB-Python(这是一个很棒的库)构建了一个快速的解决方法。这不是一个很好的解决方案(违背了 CouchDB 的原则),但它确实有效。

    CouchDB-Python 为您提供“查询”功能,它允许您“针对数据库执行临时临时视图”。你可以阅读它here

    我所拥有的是我将 javascript 函数作为字符串存储在 python 中,并将它与我在 Python 中定义的变量名连接起来。

    在 some_function.py 中

    variable = value
    
    # Map function (in javascript)
    map_fn = """function(doc) {
         <javascript code>
         var survey_match = """ + variable + """;
         <javascript code>
    """
    
    # Iterates through rows
    for row in db.query(map_fn):
         <python code>
    

    它确实不漂亮,并且可能打破了一堆 CouchDB 哲学,但它确实有效。

    D

    【讨论】:

      猜你喜欢
      • 2012-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-28
      • 2013-06-14
      • 2023-04-05
      • 1970-01-01
      相关资源
      最近更新 更多