New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multiple Nesting Levels #496
Comments
Nope, Bookshelf should take care of the N + 1 query problem. Should only be 3 calls for the above, There's also a shortcut for what you're doing above. Survey.fetch({withRelated: ['questions.answers'])
.then(function(survey) {
// do something with survey, loaded with questions,
// each of which has answers
}) or if, for example you want to constrain on the questions or answers Survey.fetch({withRelated: ['questions': function(qb) {
qb.where('flagged', true)
}, 'questions.answers'])
.then(function(survey) {
// Loads all "flagged" questions, and their answers, still only 3 queries.
}) Just want to point out that for the time being, it's possible to run into the object-relational impedance mismatch problem if you fetch things too deeply... e.g. " I'm planning on addressing this with a session store for models when they're queried so all objects on the same graph will reference the same underlying record in the DB. This will also help with the saving - there is definitely a gap that needs to be filled for consistent nested saving of related models, currently you need to implement that yourself but I'd like to come up with something better this month. |
@tgriesser for the object-relational impedance mismatch couldn't we use a simple cache on the constructor to take care of this? (maybe) Something like this: https://gist.github.com/johanneslumpe/f163d62924dd9d29dff9 That was something I had done for backbone-associations, but it should be possible to adapt it I guess. You already mentioned you want to use some kind of session store, just wanted to throw this out there in case it helps. Since this works with reference counting for removing objects from the cache when they're not used anymore it might be useful to actually use weakmaps to get rid of that step. Will the session store be limited to a single request? Or how do want to define a session? |
Thank you for those examples, that's great. Thanks for the tip on on mismatch as well. I will be aware of that as it comes up. Could I ask how Bookshelf saves (creates) to the DB with multiple nested objects? Let's say we're creating a new survey with 3 questions and 5 answers for each question. I could see Bookshelf doing it in 19 inserts: one for survey, one for 3 questions, one for 15 answers. I could also see 3 queries again: one for survey, one for 3 questions, one for 15 answers. I would guess updates are different and would be a on DB query for each item to updated. (Though I could see all the updates for a particular table in a single statement, but that might be overkill). Thanks again for answering, I appreciate knowing what's going on behind the scenes when working with an ORM. You can close the issue, or leave it open for reference! |
Bookshelf does not handle related updates or nested objects for saving. If you're inserting multiple objects your best bet is dropping to knex to handle the batch inserts and any transaction logic. The nice thing is that you can use the ORM or the query builder together. |
This is a question/discussion.
In a multi-nested relationship, what is a good way to get to the lower relationships? Example,
Survey --> hasMany('Questions')--> hasMany('Answers')
. How do I query a survey with full tree?Being able to access MySQL in those 5 lines saved a lot of time, so thanks for Bookshelf.js : )
This works, and I think the DB calls made are: 1 for survey and all questions + N for the number of questions from which to get answers. Feels like a lot of DB access.
I tried to define my Survey model with an
answers
attribute that wasthis.hasMany('Answers').through('Question')
, but it only retrieved answers for question 1, not question 2. Also, the answers were not nested within the question, but ananswers
array within thesurvey
.Should I instead create my Answer model that
belongsTo('Survey').through('Question')
, and fetch all answers with a particular survey ID? Might be more model setup than that. And my JSON tree might be inverted.I could make a large Knex query, and after getting all the data, nest answers into questions, and questions into surveys, simply manipulating the JSON tree. But then I'm just using Knex.js, and not really Bookshelf (the things wouldn't be models).
I just want to be aware of what's going on with the ORM. Is there a more streamlined way? Anything worth trying?
I'd have similar questions about saving, but would guess it's a different discussion for
CREATE
vsUPDATE
as well.The text was updated successfully, but these errors were encountered: