-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Recursive inclusion of related models #3454
Comments
waiting for this feature |
Plus one |
let me know if we can contribute |
@upscreen , it would be nice to have your contribution. See our Contributing guide and Submitting a pull request to LoopBack 4 to get started. |
Waiting for this feature also. |
@agnes512 Can you clarify? |
@malek0512 @st119848 @eyasalmamoun @upscreen I think this is being done in the issue #3453 and the PR #4263. The documentations can be found in the Query multiple relations section of each relation. @raymondfeng from the description, I think the feature is already implemented, and I didn't realize until you ping me, thanks. Closing it. |
Is there any way to include nested relationships infinitely/to N degrees using this? For example, @model()
export class Comment extends Entity {
// ...
@hasMany(() => Comment, {keyTo: 'replyTo'})
replies: Comment[]; My current attempt is: let scopeRecurse: any = {relation: "replies", scope: {}};
scopeRecurse.scope.include = [scopeRecurse];
const filter: Filter = {
// ...
include: [scopeRecurse]
}
const comments: CommentWithRelations[] = await this.postRepository.comments(id).find(filter); but this only includes the first level. Ideally there would be some sort of option for recursive relationships, ie |
Yes, that's what I'm trying to do, except the same relation nested an infinite amount of times. So comments have many replies, what I'm trying to do is fetch a comment, its replies, its replies' replies, its replies' replies' replies, etc. until there's no more replies. The code I posted is the same as what you posted, is a trick to essentially get: let scopeRecurse = {relation: "replies", scope: {include: [scopeRecurse]} If you try to access each level you get: scopeRecurse.relation // replies
scopeRecurse.scope.include[0].relation // replies
scopeRecurse.scope.include[0].relation // replies
scopeRecurse.scope.include[0].scope.include[0].relation // replies However many levels deep you go. I'd expect this to fetch replies for every comment fetched by the query, no matter how many levels deep, but instead it only fetches the first level of replies. |
@tcmal we don't support recursive inclusion in such form |
@tcmal I just tried it on my end, and it seems work. @property({
type: 'number',
id: true,
generated: true,
})
id: number;
@property({
type: 'string',
})
content?: string;
@hasMany(() => Comment)
replies: Comment[];
@property({
type: 'number',
})
commentId?: number; My repository: export class CommentRepository extends DefaultCrudRepository<
Comment,
typeof Comment.prototype.id,
CommentRelations
> {
public readonly replies: HasManyRepositoryFactory<Comment, typeof Comment.prototype.id>;
constructor(
@inject('datasources.db') dataSource: DbDataSource,
) {
super(Comment, dataSource);
this.replies = this.createHasManyRepositoryFactoryFor('replies', Getter.fromValue(this));
this.registerInclusionResolver('replies', this.replies.inclusionResolver);
}
} With filter:
I got the expected result. I am not sure if something's wrong with |
I might not be explaining myself right. I have data: {
"1": "{\"content\":\"a\",\"commentId\":1}",
"2": "{\"replyTo\":1,\"content\":\"b\",\"commentId\":2}",
"3": "{\"replyTo\":2,\"content\":\"c\",\"commentId\":3}",
"4": "{\"replyTo\":3,\"content\":\"d\",\"commentId\":4}",
"5": "{\"replyTo\":4,\"content\":\"e\",\"commentId\":5}",
"6": "{\"replyTo\":5,\"content\":\"f\",\"commentId\":6}",
} In this case I'm expecting it to return all 6 of those comments, but when I try your example it only returns up to c:
|
Sorry I didn't make it clear. The example I have above is to check if it works well with nested relations. And it does. As for recursively querying the related data, we currently don't support such a recursive way due to the design. i.e you will need to write the filter yourself to query a certain levels of relations. The filter above is an example that queries two levels of For your case, you need to set the
|
Would it be possible to have this implemented? At the very least as a helper function that returns the nested struct: let atEachLevel = {relation: "replies"}
let root = {...atEachLevel};
let currentNode = root;
for (let n = 0; n < maxDepth; n++) {
currentNode.scope = {include: [{...atEachLevel}]};
currentNode = currentNode.scope.include[0];
} |
In LB3, it's possible to recursively include models related to included models. Let's implement that feature in LB4 too.
For example, consider the domain model where
Author
has manyPost
instances and eachPost
instance has manyComment
instances.Users can fetch authors with posts and comments using the following query:
LB3 also offer few simpler alternatives how to express the same query:
LB3 test suite:
loopback-datasource-juggler/test/include.test.js#L175-L195
See also #3387
Acceptance criteria
TBD - will be filled by the team.
The text was updated successfully, but these errors were encountered: