Some of these examples are not equivalent. For example,
r
.db('dragonball')
.table('characters')
.filter(function(row){
return row('maxStrength').gt(700000).and(row('species').contains('Saiyan'));
})
.orderBy(r.desc('maxStrength'));
presumably returns one row per character, whereas SELECT c.*
FROM characters c
INNER JOIN character_species cs ON c.id = cs.character_id
INNER JOIN species s ON cs.species_id = s.id
WHERE max_strength > 700000
AND s.name = 'Saiyan'
ORDER BY max_strength DESC;
returns at least one row per character. Rather, the equivalent SQL (depending on what syntax is available) might be: SELECT c.*
FROM characters c
WHERE max_strength > 700000
AND EXISTS (SELECT NULL
FROM character_species cs
INNER JOIN species s ON cs.species_id = s.id
WHERE c.id = cs.character_id
AND s.name = 'Saiyan')
ORDER BY max_strength DESC;
The above returns one row per character, no matter how many matching entries there are in `character_species` or `species`.Pursuing this a little further then, suppose you wanted to expand your search to include humans and androids. In SQL, only a slight modification is needed:
SELECT c.*
FROM characters c
WHERE max_strength > 700000
AND EXISTS (SELECT NULL
FROM character_species cs
INNER JOIN species s ON cs.species_id = s.id
WHERE c.id = cs.character_id
AND s.name IN ('Saiyan', 'Human', 'Android'))
ORDER BY max_strength DESC;
I shudder to think what that would look like in functional form. Something like this? r
.db('dragonball')
.table('characters')
.filter(function(row){
return row('maxStrength').gt(700000).and(row('species').contains('Saiyan')).or(row('species').contains('Human')).or(row('species').contains('Android'));
})
.orderBy(r.desc('maxStrength'));
But how would it know how to group the disjunctions?In my very limited experience, examples like these always look so tantalizing until you start taking them a little further and then you quickly realize there's no such thing as a free lunch. In this case, you pay for the flexibility of RethinkDB with the expressiveness SQL.