代码之家  ›  专栏  ›  技术社区  ›  Little Bobby Tables

如何在map reduce数据库中实现引用?

  •  3
  • Little Bobby Tables  · 技术社区  · 15 年前

    我开始研究地图还原数据库。如何在map reduce数据库(如couchdb或mongodb)中实现引用?例如,假设我有司机和车,我想标记一些司机驾驶一辆车。在SQL中,它类似于:

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

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

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

    映射约简是什么等价于这种关系?

    2 回复  |  直到 8 年前
        1
  •  2
  •   Sam Bisbee    15 年前

    在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 有关如何在键中对项进行排序/称重的详细信息。

    这也可以很好地扩展,因为我们可以向map函数中添加更多信息,而不必在客户机中更改查询。假设我们添加了一个赞助商doctype:我们只添加了另一个 elseif 对于doctype字段,然后 emit([doc.driver, 2], doc); . 现在,我们可以使用上面相同的键范围查询在一个请求中提取所有三个文档。

    当然,您也可以指定单独的文档,而不是全部提取它们。 ?key=["driver's _id", 1] 只为指定的司机拉车。

    干杯。

        2
  •  1
  •   Niels van der Rest    15 年前

    在文档数据库中,可以将相关对象嵌入到拥有这些对象的文档中,例如,驱动程序文档还包含属于驱动程序的所有汽车。这就是文档数据库的强大功能;它们允许您轻松存储非规范化的数据。

    {
      "_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数据库的方式处理文档之间的关系。您的应用程序负责实施和维护这些关系。