thinky icon indicating copy to clipboard operation
thinky copied to clipboard

Alternative design for hasAndBelongsToMany

Open deoqc opened this issue 9 years ago • 3 comments

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 order and then orderBy it.
  • 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.

deoqc avatar Sep 01 '16 14:09 deoqc

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.

neumino avatar Sep 14 '16 02:09 neumino

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.

deoqc avatar Sep 14 '16 03:09 deoqc

@neumino arbitrary data in relations would be extremely useful. What's the current limitation that means this isn't possible?

stephenmuss avatar Sep 27 '16 06:09 stephenmuss