Cloudant 1到很多功能

时间:2015-07-12 20:52:10

标签: couchdb cloudant

我刚刚开始使用Cloudant而我无法理解地图功能。我一直在摆弄下面的数据,但它并没有按照我的预期进行。

关系是,用户可以有很多车辆。车辆属于1个用户。车辆'userId'是用户的关键。有一些冗余,因为用户_id和userId是相同的,后来不需要猜测。

无论如何,我怎样才能找到一个/每个用户,属于它的车辆?我最接近试验和错误的结果是显示每辆车的车主,但我想反过来,用户和属于它的车辆。我发现的所有示例都使用另一个“加入”两个或更多文档的文档,但我不需要这样做?

正确方向的任何一点都值得赞赏 - 我真的不知道。

function (doc) {
 if (doc.$doctype == "vehicle")
 {
     emit(doc.userId, {_id: doc.userId});
 }
}

编辑:越来越近了。我不确定我到底想要什么,但结果看起来有点乱 - '。行[0]是用户文档,行[n> 0]是车辆文件。我认为使用启动键/结束键时它很好,但没有结果有点混乱。

function (doc) {
     if (doc.$doctype == 'user') {
        emit([doc._id, 0], doc);
     } else if (doc.$doctype == 'vehicle') {
        emit([doc.userId, 1, doc._id], doc);
     }
}

用户被描述为

{
  "_id": "user:10",
  "firstname": “firstnamehere",
  "secondname": “secondnamehere",
  "userId": "user:10",
  "$doctype": "user"
}

车辆被描述为,

{
  "_id": "vehicle:4002”,
  “name”: “avehicle”,
  "userId": "user:10",
  "$doctype": "vehicle",
}

1 个答案:

答案 0 :(得分:1)

你正朝着正确的方向前进!你已经掌握了全局ID。以某种形式将文档的类型作为ID的一部分是一个非常好的主意,以便您以后不会感到困惑(所有文档都在同一个" pot")。

以下是您当前解决方案的一些小问题(在回答您的实际问题之前):

  • 不要在emit(key, value)中将文档作为值发出。您始终可以通过查询include_docs=true来请求属于视图行的文档。将doc作为视图值可以大大增加视图索引。如果您不需要特定值,请使用emit(key, null)

  • 您也不需要发票值中的ID。您无论如何都会获得属于视图行的文档的ID。

查看整理

现在解决您的用户聚合车辆的问题。你得到了正确的基本模式。此模式称为查看排序规则,您可以阅读更多相关信息in the CouchDB docs(忽略它位于" Couchapp"部分)。

使用视图排序规则的技巧是您返回两种或更多类型的文档,但要确保它们以允许直接分组的方式排序。因此,了解CouchDB如何对视图结果进行排序非常重要。有关该collation specification的更多信息,请参阅Step-by-step guide to build Qt-SQL-driver-plugin for SQLite-DB with SQLCipher-extension。理解视图排序规则的一个重要关键是具有数组键的行按键元素排序。因此,当两行具有相同的key[0]时,它们按key[1]排序。如果相同,则考虑key[2],依此类推。

您的地图功能frist按用户ID(key[0])对用户和车辆进行分组。然后,您的地图函数会使用0在密钥的第二个元素中1之前排序的事实,因此您的视图将包含以下内容:

  • 用户1
  • 用户1的车辆
  • 用户1的车辆
  • 用户1的车辆
  • 用户2
  • 用户3
  • 用户3的车辆
  • 用户4

如您所见,用户的车辆会立即跟随他们的用户。因此,您可以将此结果分组为聚合,而无需执行昂贵的排序或查找操作。

请注意,用户根据其ID进行排序,用户内的车辆也会根据其ID进行排序。这是因为您使用了键数组中的ID。

创建查询

如果您无法根据自己的需求进行查询,那么该视图并不值得。您拥有的视图支持以下查询:

  • 让所有用户使用他们的车辆
  • 让一系列用户使用他们的车辆
  • 使用其车辆获得单个用户
  • 获取没有车辆的单个用户(您也可以使用_all_docs视图)

"用户1和用户3(包括)之间的所有用户及其车辆的示例查询"

我们想要查询范围,因此我们在查询中使用startkeyendkey

startkey=["user:1", 0]
endkey=["user:3", 1, {}]

请注意使用{}作为哨兵值,这是必需的,以便结束键大于任何具有["user:3", 1, (anyConceivableVehicleId)]

键的行