2016-05-27 4 views
1

В настоящее время я пытаюсь выяснить, подходит ли CouchDB для моего прецедента, и если да, то каким образом. У меня есть ситуации, подобные следующему:Несколько соединений в CouchDB

Первого набора документов (назовем их компанию):

{ 
    "_id" : 1, 
    "name" : "Foo" 
} 

{ 
    "_id" : 2, 
    "name" : "Bar" 
} 

{ 
    "_id" : 3, 
    "name" : "Baz" 
} 

Второго набор документов (давайте называть их проекты):

{ 
    "_id" : 4, 
    "name" : "FooProject1", 
    "company" : 1 
} 

{ 
    "_id" : 5, 
    "name" : "FooProject2", 
    "company" : 1 
} 
... 
{ 
    "_id" : 100, 
    "name" : "BazProject2", 
    "company" : 3 
}  

Третьими набор документов (назовем их инцидентами):

{ 
    "_id" : "300", 
    "project" : 4, 
    "description" : "...", 
    "cost" : 200 
} 

{ 
    "_id" : "301", 
    "project" : 4, 
    "description" : "...", 
    "cost" : 400 
} 

{ 
    "_id" : "302", 
    "project" : 4, 
    "description" : "...", 
    "cost" : 500 
} 
    ... 

Итак, короче каждая компания ha много проектов, и каждый проект может иметь несколько инцидентов. Одной из причин, по которым я моделирую данные, является то, что я прихожу в основном из фона SQL, поэтому моделирование может быть совершенно неподходящим. Вторая причина заключается в том, что я хотел бы добавить новые инциденты очень легко, просто используя REST-API, предоставленный couchdb. Таким образом, инциденты должны быть едиными документами.

Однако теперь я хотел бы получить представление, которое позволит мне рассчитать общую стоимость для каждой компании. Я могу легко определить представление, используя map-reduce и связанные документы, которые получают мне общую сумму за проект. Однако, как только я нахожусь на уровне проекта, я не могу дойти до уровня компании.

Возможно ли это вообще с помощью couchDb? Такие обобщающие данные звучат как идеальный вариант использования для уменьшения карты. В SQL я бы просто сделал соединение из трех таблиц, но похоже, что в couchDb лучшее, что я могу получить, - это соединения из двух таблиц.

+0

Вы не можете (или, по крайней мере, не должны) делать какие-либо соединения в CouchDB. Вы можете использовать функции списка, чтобы объединить соседние строки (сортировка), но все остальное будет разрушать вашу производительность. – OrangeDog

ответ

2

Как уже упоминалось, вы не можете делать соединения в CouchDb, но это не ограничение, это приглашение как думать о ваших проблемах, так и подходить к ним по-разному. Правильный способ сделать это в CouchDB является определение структуры данных, называемые, например: IncidentReference состоят из:

  • Проект ID
  • И идентификатор компании

Таким образом, ваши данные будут выглядеть :

{ 
    "_id" : "301", 
    "project" : 4, 
    "description" : "...", 
    "cost" : 400, 
    "reference" : { 
     "projectId" : 1, 
     "companyId" : 2 
    } 
} 

Это нормально. После этого вы можете играть с Map/Reduce, чтобы добиться того, чего хотите. Вообще говоря, вам нужно подумать о том, как вы собираетесь запрашивать свои данные.

+0

Итак, насколько я понимаю это, с точки зрения SQL, вы действительно должны отказаться от какой-либо нормализации? Потому что с этим инцидентомReference у меня теперь есть projectId и companyId, которые хранятся в ссылке, хотя проект уже содержит компанию (дублированные данные). Итак, каков наилучший способ, чтобы данные не становились непоследовательными? – LiKao

+1

Вы все равно должны быть осторожны с денормализацией вообще, например, если вы денормализовали имя клиента и это имя изменилось, это становится трудно управлять. Однако, как правило, безопасно иметь столько ссылок (идентификаторов) для других объектов, сколько вам нужно. Если вы думаете об этом, крайне редко, что эти ссылки устарели (как может инцидент больше не принадлежать этому проекту? Или этой компании). Просто убедитесь, что эти ссылки участвуют в определении личности вашего документа, личность не меняется :) – reddy

Смежные вопросы