25Май/100
Ссылки на объекты других коллекций в MongoDB
В MongoDB есть хорошая фича: объекты в одной коллекции могут ссылаться на объекты в другой. Товарищ zit в комментариях попросил показать, как этим пользоваться. Вот краткое руководство
Интерактивная консоль
В интерактивной консоли Mongo создание и использование ссылки на другую коллекцию выглядит так:
// Создаём первую таблицу, с танками abrams = {'name':'M1 Abrams', 'weight':61300, 'speed': 48.3}; t90 = {'name': 'T-90', 'weight': 46500, 'speed': 60}; db.tanks.save(abrams); db.tanks.save(t90); // Смотрим её содержимое db.tanks.find(); /* { "_id" : ObjectId("4bfa5dfd6ff2f1afd7f98394"), "name" : "M1 Abrams", "weight" : 61300, "speed" : 48.3 } { "_id" : ObjectId("4bfa5dfd6ff2f1afd7f98395"), "name" : "T-90", "weight" : 46500, "speed" :60 }*/ // получаем id обоих танков var abrams_id = db.tanks.findOne({'name':'M1 Abrams'})._id var t90_id = db.tanks.findOne({'name':'T-90'})._id // Создаём два объекта игроков, каждый со своим танком, сохраняем в базу player1 = {'name':'kze', 'score':0, 'tank': new DBRef('tanks', abrams_id)}; db.players.save(player1) player2 = {'name':'vls', 'score':10, 'tank': new DBRef('tanks', t90_id)}; db.players.save(player2) db.players.find() /* { "_id" : ObjectId("4bfa5dfe6ff2f1afd7f98396"), "name" : "kze", "score" : 0, "tank" : { "$ref" : "tanks", "$id" : ObjectId("4bfa5dfd6ff2f1afd7f98394") } } { "_id" : ObjectId("4bfa5dfe6ff2f1afd7f98397"), "name" : "vls", "score" : 10, "tank" : { "$ref" : "tanks", "$id" : ObjectId("4bfa5dfd6ff2f1afd7f98395") } }*/ // Получаем очки игрока db.players.findOne({'name':'kze'}).score // 0 // Получаем скорость танка игрока по ссылке db.players.findOne({'name':'kze'}).tank.fetch().speed // 48.3 db.players.findOne({'name':'vls'}).tank.fetch().speed // 60
Node.js
В Node.js всё делается не так просто (в основном из-за требований к асинхронности). Нам надо явно получать объект по ссылке. Вот так выглядит примерно такой же запрос как указан выше (на той же базе данных):
var mongo = require('../lib/mongodb'), sys = require('sys'); var host = process.env['MONGO_NODE_DRIVER_HOST'] != null ? process.env['MONGO_NODE_DRIVER_HOST'] : 'localhost'; var port = process.env['MONGO_NODE_DRIVER_PORT'] != null ? process.env['MONGO_NODE_DRIVER_PORT'] : mongo.Connection.DEFAULT_PORT; sys.puts("Connecting to " + host + ":" + port); var db = new mongo.Db('node-mongo-examples', new mongo.Server(host, port, {}), {}); db.open(function(err, db) { db.collection('players', function(err, collection) { collection.findOne({"name":'kze'}, function(err, player){ // Получаем объект, на который ссылается player.tank db.dereference(player.tank, function(err, tank) { sys.puts('Player ' + player.name + ' tank speed is ' + tank.speed); }); }); }); });
В качестве коннектора используется node-mongodb-native. Если нам надо создать объект со ссылкой, ссылка создаётся явно:
player.tank = new mongo.DBRef('tanks', tank._id, null);
Ссылки по теме
- Database References в документации MongoDB
- Выбор схемы БД в документации MongoDB
- Использование MongoDB в Node.js
Источник: Механический мир
