thinky
thinky copied to clipboard
Alternative design for hasAndBelongsToMany
The current implementation of hasAndBelongsToMany gives only the relational database way of dealing with it: add and auxiliary table to hold the relation of these 2 indexes.
I found this not to be the best approach in all of my use cases. I rather have this approach:
const Post = thinky.createModel('post', {
id: type.string().uuid(4),
author: type.string(),
tags: type.array().schema(type.string().uuid(5)), // <-- array of tags id's
})
Post.ensureIndex('tags', {mult: true}) // <-- efficient way to query all post's with some tag
const Tag = thinky.createModel('tag'. {
id: type.string().uuid(4),
tag: type.string(),
})
Now I can query like this:
r.table('tag').getAll(r.args(post.tags)) // get all post tags
r.table('post').getAll(tag.id, {index: 'tags'}) // get all posts with some tag with
Wouldn't it be nice to have this supported by thinky?
It would a relation similar to hasAndBelongsToMany - can't come up with a name - but not symmetric.
In this case, we could just do:
// shape of result same as hasAndBelongsToMany
Post.getJoin({ tags: true })
Tag.getJoin({ posts: true })
This approach is advantageous for me due to few things:
- It seemed more performant, for obvious reasons, but I didn't profile it.
- Sometimes the order matter, and seems more straight forward to keep the keys ordered than to have an field
orderand thenorderByit. - Sometimes I need to handle directly, instead of through thinky, and it shown to be easier. Usually the relation in real word is not symmetric, and was always better not to treat it as if it was.
ps: I tried to find issues related to this, since is not by far an original idea, but found none.
Thinky used to implement n-n relations like this (a long time ago), but it was a huge pain to maintain. Updating an array is somehow very annoying with ReQL.
As for the performance, your solution is not always more performant since your document are bigger. It all depends on your workload.
Order is a fair point, thinky currently doesn't let you do that. Maybe when we can store abitrary data in the relation it will be possible, but at least it's not at the moment.
My use cases is for n-n in one direction are small (usually 2 or 3) - e.g. a post have few tags - so document is not very big .
The other direction tends to be huge - e.g. a tag has a lot of posts - but it doesn't affect directly the document. It may have implications in the index size though.
@neumino arbitrary data in relations would be extremely useful. What's the current limitation that means this isn't possible?