MongoDB - Отношения

Отношения в MongoDB представляют, как различные документы логически связаны друг с другом. Отношения можно смоделировать с помощьюEmbedded и Referencedподходы. Такие отношения могут быть 1: 1, 1: N, N: 1 или N: N.

Рассмотрим случай хранения адресов для пользователей. Таким образом, у одного пользователя может быть несколько адресов, что соответствует соотношению 1: N.

Ниже приводится образец структуры документа user документ -

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "name": "Tom Hanks",
   "contact": "987654321",
   "dob": "01-01-1991"
}

Ниже приводится образец структуры документа address документ -

{
   "_id":ObjectId("52ffc4a5d85242602e000000"),
   "building": "22 A, Indiana Apt",
   "pincode": 123456,
   "city": "Los Angeles",
   "state": "California"
}

Моделирование встроенных отношений

При встроенном подходе мы встроим адресный документ в пользовательский документ.

> db.users.insert({
	{
		"_id":ObjectId("52ffc33cd85242f436000001"),
		"contact": "987654321",
		"dob": "01-01-1991",
		"name": "Tom Benzamin",
		"address": [
			{
				"building": "22 A, Indiana Apt",
				"pincode": 123456,
				"city": "Los Angeles",
				"state": "California"
			},
			{
				"building": "170 A, Acropolis Apt",
				"pincode": 456789,
				"city": "Chicago",
				"state": "Illinois"
			}
		]
	}
})

При таком подходе все связанные данные хранятся в одном документе, что упрощает извлечение и обслуживание. Весь документ можно получить одним запросом, например:

>db.users.findOne({"name":"Tom Benzamin"},{"address":1})

Обратите внимание, что в приведенном выше запросе db и users - база данных и коллекция соответственно.

Недостатком является то, что если встроенный документ продолжает слишком сильно увеличиваться в размере, это может повлиять на производительность чтения / записи.

Моделирование ссылочных отношений

Это подход к построению нормализованных отношений. При таком подходе и пользовательский, и адресный документы будут поддерживаться отдельно, но пользовательский документ будет содержать поле, которое будет ссылаться на адресный документ.id поле.

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin",
   "address_ids": [
      ObjectId("52ffc4a5d85242602e000000"),
      ObjectId("52ffc4a5d85242602e000001")
   ]
}

Как показано выше, пользовательский документ содержит поле массива address_idsкоторый содержит ObjectIds соответствующих адресов. Используя эти ObjectIds, мы можем запрашивать адресные документы и получать оттуда данные адреса. При таком подходе нам потребуются два запроса: первый для полученияaddress_ids поля из user документ и второй, чтобы получить эти адреса из address коллекция.

>var result = db.users.findOne({"name":"Tom Benzamin"},{"address_ids":1})
>var addresses = db.address.find({"_id":{"$in":result["address_ids"]}})