【问题标题】:How to implement references in map-reduce databases?如何在 map-reduce 数据库中实现引用?
【发布时间】:2010-08-05 09:14:57
【问题描述】:

我开始研究 map-reduce 数据库。如何在 CouchDB 或 MongoDB 等 map-reduce 数据库中实现引用?例如,假设我有司机和汽车,我想标记某个司机驾驶汽车。在 SQL 中是这样的:

SELECT person_id, car_id FROM driver, car WHERE driver.car = car.car_id

(也就是说,如果我没记错的话——我已经有一段时间没有用 SQL 编程了。)

在具有引用的语言中,它变得更加简单:Person 的实例可以指向 Car 的实例。

什么是 map-reduce 等价于这种关系?

【问题讨论】:

    标签: mongodb mapreduce couchdb nosql


    【解决方案1】:

    在 CouchDB 中,您将编写一个 map/reduce,输出所有具有复杂键的汽车和驾驶员,然后使用键范围来选择两者。例如,假设您的文档看起来像这两个...

    {
      "_id": "...",
      "_rev": "...",
      "docType": "driver"
    }
    
    {
      "_id": "...",
      "_rev": "...",
      "docType": "car",
      "driver": "driver's _id"
    }
    

    您可以使用duck typing 而不是指定 docType,但我更喜欢这种方法。

    你的地图功能:

    function(doc)
    {
      if(doc.docType == "driver")
        emit([doc.id, 0], doc);
      elseif(doc.docType == "car")
        emit([doc.driver, 1], doc];
    }
    

    我们的复杂键是一个数组,第一项总是驱动程序的_id。数组中的第二项防止键碰撞,并允许我们直接引用汽车或驾驶员(稍后会详细介绍)。

    我们现在可以使用键范围查询参数来获取两个文档。

    ?startkey=["driver _id"]&endkey=["driver _id", {}]
    

    这基本上是说“给我任何以驱动程序 _id 作为第一项的数组,以及第二项中的任何内容。这是因为对象 - endkey 数组中的第二项 - 被排序为最高。请参阅http://wiki.apache.org/couchdb/View_collation?redirect=ViewCollation#Collation_Specification 了解有关如何在键中对项目进行排序/加权的更多信息。

    这也可以很好地扩展,因为我们可以在地图函数中添加更多信息,而无需更改客户端中的查询。假设我们添加了一个赞助商 docType:我们只需为 docType 字段添加另一个 elseif,然后添加 emit([doc.driver, 2], doc);。现在我们可以从上面使用相同的键范围查询将所有三个文档拉到一个请求中。

    当然,您也可以指定单个文档,而不是拉出所有文档。 ?key=["driver's _id", 1] 只会为指定的司机拉车。

    干杯。

    【讨论】:

      【解决方案2】:

      在文档数据库中,您可以将相关对象嵌入到拥有对象的文档中,例如司机文件还包含属于司机的所有汽车。这就是文档数据库的力量;它们允许您轻松存储非规范化数据。

      {
        "_id": "joe_the_driver",
        "name": "Joe",
        "cars": [
          { "_id": "123-AB", /* car properties */ },
          { "_id": "456-YZ", /* car properties */ }
        ]
      }
      

      此格式仅适用于一对多关系。如果司机和汽车之间的关系是多对多的,则必须创建查找文档:

      {
        "_id": "joe_the_driver",
        "car_ids": [ /* ID's that refer to car documents */ ]
      }
      
      {
        "_id": "123-AB",
        "driver_ids": [ /* ID's that refer to driver documents */ ]
      }
      

      请务必注意,大多数文档数据库无法像 SQL 数据库那样强制文档之间的关系。您的应用程序负责强制执行和维护这些关系。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-21
        • 2011-05-21
        • 1970-01-01
        • 2022-06-15
        相关资源
        最近更新 更多