【发布时间】:2016-06-09 21:30:09
【问题描述】:
假设我正在创建一个 Cloudant 数据库来存储我车队的所有服务记录(我没有,但问题几乎相同。)为此,我有两种类型的记录:
汽车:
{
"type": "Car",
"_id": "VIN 1",
"plateNumber": "ecto-1",
"plateState": "NY",
"make": "Cadillac",
"model": "Professional Chassis",
"year": 1959
}
{
"type": "Car",
"_id": "VIN 2",
"plateNumber": "mntclmbr",
"plateState": "VT",
"make": "Jeep",
"model": "Wrangler",
"year": 2016
}
及服务记录:
{
"type": "ServiceRecord",
"_id": "service1",
"carServiced": "VIN 1",
"date": [1984, 6, 8],
"item": "Cleaning (Goo)",
"cost": 300
}
{
"type": "ServiceRecord",
"_id": "service2",
"carServiced": "VIN 1",
"date": [1984, 6, 9],
"item": "Cleaning (Marshmellow)",
"cost": 800
}
{
"type": "ServiceRecord",
"_id": "service3",
"carServiced": "VIN 2",
"date": [2016, 4, 2],
"item": "Alignment",
"cost": 150
}
关于它的工作原理有几点需要注意:
- 永远不会改变汽车的 VIN 号用作文档 _id。
- 如果汽车在新州注册或使用新车牌号,则不应丢失汽车的服务记录。
- 由于汽车数量众多,并且需要维修的频率很高,如果需要添加、删除或更改服务记录,则编辑汽车文档是不合理的。
目前,我有几个视图可以查找信息。
首先,我有一张从车牌到 VIN 的地图:
function(doc){
if (doc.type == "Car"){
emit([doc.plateState, doc.plateNumber], doc._id);
}
}
// Results in:
["NY", "ecto-1"] -> "VIN 1"
["VT", "mntclmbr"] -> "VIN 2"
其次,我有一张从所有汽车的 VIN 到服务记录的地图:
function(doc){
if (doc.type == "ServiceRecord"){
emit(doc.carServiced, doc);
}
}
// Results in:
"VIN 1" -> {"_id": "service1", ...}
"VIN 1" -> {"_id": "service2", ...}
"VIN 2" -> {"_id": "service3", ...}
最后,我有一张地图,从所有汽车的 VIN 和服务日期到该日期发生的特定服务:
function(doc){
if (doc.type == "ServiceRecord"){
var key = [doc.carServiced, doc.date[0], doc.date[3], doc.date[2]];
emit(key, doc);
}
}
// Results in:
["VIN 1", 1984, 6, 8] -> {"_id": "service1", ...}
["VIN 1", 1984, 6, 9] -> {"_id": "service2", ...}
["VIN 2", 2016, 4, 2] -> {"_id": "service3", ...}
通过这三张地图,我可以找到三种不同的东西:
- 任何汽车的车牌识别号。
- 任何汽车的服务记录(按 VIN)。
- 任何汽车在任何特定年份、月份或日期的 VIN 服务记录。
但是,无法通过车牌找到汽车的所有服务记录。 (至少不是一步。)为此,我需要一张这样的地图:
["NY", "ecto-1"] -> {"_id": "service1", ...}
["NY", "ecto-1"] -> {"_id": "service2", ...}
["VT", "mntclmbr"] -> {"_id": "service3", ...}
更复杂的是,我希望能够按车牌和日期查找服务记录,使用如下地图:
["NY", "ecto-1", 1984, 6, 8] -> {"_id": "service1", ...}
["NY", "ecto-1", 1984, 6, 9] -> {"_id": "service2", ...}
["VT", "mntclmbr", 2016, 4, 2] -> {"_id": "service3", ...}
不幸的是,我不知道如何生成这样的地图,因为密钥需要来自两个文档的信息。我只能从 Car 文档中获取车牌信息,而我只能从 ServiceRecord 文档中获取服务信息(包括文件 _id 的 emit 值)。
到目前为止,我唯一的想法是做两个查询:一个从车牌信息中获取 VIN,另一个从 VIN 中获取服务记录。它们将是快速查询,所以这不是一个大问题,但我觉得有更好的方法。
有谁知道更好的方法是什么?
(奖励:两次查询方法不允许以有效的方式按状态查找所有服务记录。我描述的最后一张地图可以做到这一点。因此,任何可以描述解决方案的人都可以获得互联网积分它也提供了该功能。)
**编辑:另一个问题,here,被建议为可能的重复。这绝对是一个类似的问题,但是提供的解决方案并不能解决这个问题。具体来说,最佳解决方案建议将文档的位置存储在树中。在这种情况下,这将类似于 ServiceRecord 文档中的 "index":[State, Number, Year, Month, Day]"。但是,我们不能这样做,因为车牌信息很容易改变。
【问题讨论】:
标签: join view couchdb cloudant relational-algebra