When traversing deep object graphs, more mature ORMs generate efficient SQL code that uses relational joins to traverse the connections. As far as I can tell by the documentation, there is no way to do the same in node-orm. For example, the code
var orm = require('orm');
orm.settings.set("connection.debug", true);
orm.connect('sqlite://dummy.sqlite', function(err, db) {
var A = db.define('a', {name:{type:'text'}},{cache: false});
var B = db.define('b', {name:{type:'text'}},{cache: false});
var AToB = db.define('atob', {},{cache: false});
AToB.hasOne('a',A, {reverse:'bs'});
AToB.hasOne('b',B, {reverse:'as'});
db.sync(function() {
var newBs = [];
for(var i = 0; i < 5; i++)
newBs.push({name:'b'+i});
B.create(newBs, function(err,bs) {
var newAs = [];
for(var i = 0; i<5; i++)
newAs.push({});
A.create(newAs, function(err,as) {
var conns = [];
for(var a in as)
for(var b in bs)
conns.push({a:a,b:b});
AToB.create(conns, function(err, conns) {
AToB.findByB({name:'b2'}).each(function(conn) {
A.findByBs(conn).each(function(a) {
console.log(JSON.stringify(a));
});
});
});
});
});
});
});
fetches all As that are connected to B with the id 2 using one SQL query per AToB instance (effectively calculating the join by hand). The output looks like this:
(orm/sqlite) SELECT * FROM sqlite_master WHERE type = 'table' and name = 'a'
(orm/sqlite) CREATE TABLE `a` (`name` TEXT, `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT)
(orm/sqlite) SELECT * FROM sqlite_master WHERE type = 'table' and name = 'b'
(orm/sqlite) CREATE TABLE `b` (`name` TEXT, `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT)
(orm/sqlite) SELECT * FROM sqlite_master WHERE type = 'table' and name = 'atob'
(orm/sqlite) CREATE TABLE `atob` (`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, `a_id` INTEGER, `b_id` INTEGER)
(orm/sqlite) INSERT INTO `b` (`name`) VALUES ('b0')
(orm/sqlite) INSERT INTO `b` (`name`) VALUES ('b1')
(orm/sqlite) INSERT INTO `b` (`name`) VALUES ('b2')
(orm/sqlite) INSERT INTO `b` (`name`) VALUES ('b3')
(orm/sqlite) INSERT INTO `b` (`name`) VALUES ('b4')
(orm/sqlite) INSERT INTO `a` (`name`) VALUES (NULL)
(orm/sqlite) INSERT INTO `a` (`name`) VALUES (NULL)
(orm/sqlite) INSERT INTO `a` (`name`) VALUES (NULL)
(orm/sqlite) INSERT INTO `a` (`name`) VALUES (NULL)
(orm/sqlite) INSERT INTO `a` (`name`) VALUES (NULL)
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 0 WHERE `id` = 1
(orm/sqlite) UPDATE `atob` SET `a_id` = 0, `b_id` = 0 WHERE `id` = 1
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 0 WHERE `id` = 2
(orm/sqlite) UPDATE `atob` SET `a_id` = 0, `b_id` = 1 WHERE `id` = 2
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 0 WHERE `id` = 3
(orm/sqlite) UPDATE `atob` SET `a_id` = 0, `b_id` = 2 WHERE `id` = 3
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 0 WHERE `id` = 4
(orm/sqlite) UPDATE `atob` SET `a_id` = 0, `b_id` = 3 WHERE `id` = 4
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 0 WHERE `id` = 5
(orm/sqlite) UPDATE `atob` SET `a_id` = 0, `b_id` = 4 WHERE `id` = 5
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 1 WHERE `id` = 6
(orm/sqlite) UPDATE `atob` SET `a_id` = 1, `b_id` = 0 WHERE `id` = 6
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 1 WHERE `id` = 7
(orm/sqlite) UPDATE `atob` SET `a_id` = 1, `b_id` = 1 WHERE `id` = 7
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 1 WHERE `id` = 8
(orm/sqlite) UPDATE `atob` SET `a_id` = 1, `b_id` = 2 WHERE `id` = 8
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 1 WHERE `id` = 9
(orm/sqlite) UPDATE `atob` SET `a_id` = 1, `b_id` = 3 WHERE `id` = 9
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 1 WHERE `id` = 10
(orm/sqlite) UPDATE `atob` SET `a_id` = 1, `b_id` = 4 WHERE `id` = 10
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 2 WHERE `id` = 11
(orm/sqlite) UPDATE `atob` SET `a_id` = 2, `b_id` = 0 WHERE `id` = 11
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 2 WHERE `id` = 12
(orm/sqlite) UPDATE `atob` SET `a_id` = 2, `b_id` = 1 WHERE `id` = 12
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 2 WHERE `id` = 13
(orm/sqlite) UPDATE `atob` SET `a_id` = 2, `b_id` = 2 WHERE `id` = 13
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 2 WHERE `id` = 14
(orm/sqlite) UPDATE `atob` SET `a_id` = 2, `b_id` = 3 WHERE `id` = 14
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 2 WHERE `id` = 15
(orm/sqlite) UPDATE `atob` SET `a_id` = 2, `b_id` = 4 WHERE `id` = 15
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 3 WHERE `id` = 16
(orm/sqlite) UPDATE `atob` SET `a_id` = 3, `b_id` = 0 WHERE `id` = 16
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 3 WHERE `id` = 17
(orm/sqlite) UPDATE `atob` SET `a_id` = 3, `b_id` = 1 WHERE `id` = 17
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 3 WHERE `id` = 18
(orm/sqlite) UPDATE `atob` SET `a_id` = 3, `b_id` = 2 WHERE `id` = 18
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 3 WHERE `id` = 19
(orm/sqlite) UPDATE `atob` SET `a_id` = 3, `b_id` = 3 WHERE `id` = 19
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 3 WHERE `id` = 20
(orm/sqlite) UPDATE `atob` SET `a_id` = 3, `b_id` = 4 WHERE `id` = 20
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 4 WHERE `id` = 21
(orm/sqlite) UPDATE `atob` SET `a_id` = 4, `b_id` = 0 WHERE `id` = 21
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 4 WHERE `id` = 22
(orm/sqlite) UPDATE `atob` SET `a_id` = 4, `b_id` = 1 WHERE `id` = 22
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 4 WHERE `id` = 23
(orm/sqlite) UPDATE `atob` SET `a_id` = 4, `b_id` = 2 WHERE `id` = 23
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 4 WHERE `id` = 24
(orm/sqlite) UPDATE `atob` SET `a_id` = 4, `b_id` = 3 WHERE `id` = 24
(orm/sqlite) INSERT INTO `atob` (`a_id`, `b_id`) VALUES (NULL, NULL)
(orm/sqlite) UPDATE `atob` SET `a_id` = 4 WHERE `id` = 25
(orm/sqlite) UPDATE `atob` SET `a_id` = 4, `b_id` = 4 WHERE `id` = 25
(orm/sqlite) SELECT `t1`.`id`, `t1`.`a_id`, `t1`.`b_id` FROM `atob` `t1` JOIN `b` `t2` ON `t2`.`id` = `t1`.`b_id` WHERE `t2`.`name` = 'b2'
(orm/sqlite) SELECT `t1`.`name`, `t1`.`id` FROM `a` `t1` JOIN `atob` `t2` ON `t2`.`a_id` = `t1`.`id` WHERE `t2`.`id` = 4 AND `t2`.`a_id` = 0 AND `t2`.`b_id` = 3
(orm/sqlite) SELECT `t1`.`name`, `t1`.`id` FROM `a` `t1` JOIN `atob` `t2` ON `t2`.`a_id` = `t1`.`id` WHERE `t2`.`id` = 9 AND `t2`.`a_id` = 1 AND `t2`.`b_id` = 3
(orm/sqlite) SELECT `t1`.`name`, `t1`.`id` FROM `a` `t1` JOIN `atob` `t2` ON `t2`.`a_id` = `t1`.`id` WHERE `t2`.`id` = 14 AND `t2`.`a_id` = 2 AND `t2`.`b_id` = 3
(orm/sqlite) SELECT `t1`.`name`, `t1`.`id` FROM `a` `t1` JOIN `atob` `t2` ON `t2`.`a_id` = `t1`.`id` WHERE `t2`.`id` = 19 AND `t2`.`a_id` = 3 AND `t2`.`b_id` = 3
(orm/sqlite) SELECT `t1`.`name`, `t1`.`id` FROM `a` `t1` JOIN `atob` `t2` ON `t2`.`a_id` = `t1`.`id` WHERE `t2`.`id` = 24 AND `t2`.`a_id` = 4 AND `t2`.`b_id` = 3
{"name":null,"id":1}
{"name":null,"id":2}
{"name":null,"id":3}
{"name":null,"id":4}
However, the last six (select) queries could be replaced by a single
SELECT `t1`.`name`, `t1`.`id` FROM `a` `t1`
JOIN `atob` `t2` ON `t2`.`a_id` = `t1`.`id`
JOIN `b` `t3` ON `t2`.`b_id` = `t3`.`id`
WHERE `t3`.`name` = 'b2'
When traversing deep object graphs, more mature ORMs generate efficient SQL code that uses relational joins to traverse the connections. As far as I can tell by the documentation, there is no way to do the same in node-orm. For example, the code
fetches all As that are connected to B with the id 2 using one SQL query per AToB instance (effectively calculating the join by hand). The output looks like this:
However, the last six (select) queries could be replaced by a single
if the API and the implementation supported it.