问题
This could be a stupid question if my understanding about select_related() is completely wrong.
Here is the database design that I have.
class UserAccount(Document):
first_name = StringField(max_length = 20)
last_name = StringField(max_length = 20)
user_name = StringField(max_length = 20)
friends = ListField(ReferenceField('self'))
And the queryset is:
u = UserAccount.objects.get(user_name="something").select_related()
I've passed the result in 'u' to the Django templates. So I tried this in the template.
{% for friend in u.friends %}
{% for f in friend.friends %}
{{ f.friends }}
{% endfor %}
{% endfor %}
I'm able to see the friends of friends of my friends in the browser. Isn't the work of select_related() to stop the further dereferencing that's happening here?
Correct me if i'm wrong.
回答1:
First a word of warning, this is not only a relational schema but a recursively relational one. You could follow the relationships and end up loading all the UserAccount
objects.
Remember there are no joins in MongoDB - so you are asking the client code (mongoengine) to perform in application joins for you - which means multiple queries and then assigning the results to the correct documents - thats expensive. So please ask yourself "is this the right tool for the job?"
However, your observations are correct - by default select_related() only goes down a single relation so for a user object it will only dereference the first set of friends and not their friends. You can change the depth by passing it to select_related(max_depth=2)
.
来源:https://stackoverflow.com/questions/20224141/mongoengine-deferencing-happens-after-using-select-related