Предположим, что я создаю базу данных Cloudant для хранения всех записей службы для моего парка автомобилей (я не, но проблема почти такая же.) для того, чтобы сделать это, у меня есть два типа записей:(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"
Во-вторых, я получил карту карту от VINs всех автомобилей на услугу записей:
function(doc){
if (doc.type == "ServiceRecord"){
emit(doc.carServiced, doc);
}
}
// Results in:
"VIN 1" -> {"_id": "service1", ...}
"VIN 1" -> {"_id": "service2", ...}
"VIN 2" -> {"_id": "service3", ...}
Наконец, я получил карту карты от VINs всех болидов и дат обслуживания для конкретной услуги, что произошло в тот же день:
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.
- Сервисные записи любого автомобиля по 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, и я могу получить только служебную информацию (включая документ _id для значения emit) из документов ServiceRecord.
До сих пор я думал только о двух запросах: один, чтобы получить VIN из информации о плите, а другой - получить служебные записи от VIN.Они будут быстрыми запросами, поэтому это не огромная проблема, но я чувствую, что есть лучший способ.
Кто-нибудь знает, что может быть лучшим способом?
(Бонус: метод с двумя запросами не позволяет эффективно находить все служебные записи по состоянию. Последняя карта, которую я опишу, сможет это сделать. Таким образом, бонусные интернет-точки для всех, кто может описать решение, которое обеспечивает эту функциональность.)
** Редактировать: Еще одна проблема, here, была предложена как возможный дубликат. Это определенно аналогичная проблема, однако предлагаемые решения не решают эту проблему. В частности, верхнее решение предполагает сохранение позиции документа в дереве. В этом случае это будет выглядеть как "index":[State, Number, Year, Month, Day]"
в документе ServiceRecord. Однако мы не можем этого сделать, потому что информация о пластине может легко измениться.
Возможный дубликат [Как я могу назвать другой вид в виде кушетки?] (Http://stackoverflow.com/questions/3365268/how-can-i-call-another -view-in-a-couchdb-view) –