Ich habe folgende Modelle:
User
, Customer
,Comment
Der Benutzer kann einen Kommentar abgeben Customer
, der Benutzer kann rekursiv unbegrenzt auf den Kommentar eines anderen Benutzers antworten.
Ich habe dies getan, aber es ist auf nur eine Antwort beschränkt, und ich möchte alle Antworten NESTED erhalten:
public async getCommentsForCustomerId(customerId: string): Promise<CustomerComment[]> {
return this.find({where: {customer: {id: customerId}, parentComment: null}, relations: ['childComments']});
}
Die Antwort, die ich erhalte, ist jedoch nur auf einer Ebene verschachtelt:
[
{
"id": "7b5b654a-efb0-4afa-82ee-c00c38725072",
"content": "test",
"created_at": "2019-12-03T15:14:48.000Z",
"updated_at": "2019-12-03T15:14:49.000Z",
"childComments": [
{
"id": "7b5b654a-efb0-4afa-82ee-c00c38725073",
"content": "test reply",
"created_at": "2019-12-03T15:14:48.000Z",
"updated_at": "2019-12-03T15:14:49.000Z",
"parentCommentId": "7b5b654a-efb0-4afa-82ee-c00c38725072"
}
]
}
]
Wie kann ich eine Abfrage durchführen, um sie alle in Typorm zu verschachteln?
Entitätsdefinition (Kunden in Lead umbenannt) :
@Entity('leads_comments')
export class LeadComment {
@PrimaryGeneratedColumn('uuid')
id: string;
@ManyToOne(type => LeadComment, comment => comment.childComments, {nullable: true})
parentComment: LeadComment;
@OneToMany(type => LeadComment, comment => comment.parentComment)
@JoinColumn({name: 'parentCommentId'})
childComments: LeadComment[];
@RelationId((comment: LeadComment) => comment.parentComment)
parentCommentId: string;
@ManyToOne(type => User, {cascade: true})
user: User | string;
@RelationId((comment: LeadComment) => comment.user, )
userId: string;
@ManyToOne(type => Lead, lead => lead.comments, {cascade: true})
lead: Lead | string;
@RelationId((comment: LeadComment) => comment.lead)
leadId: string;
@Column('varchar')
content: string;
@CreateDateColumn()
created_at: Date;
@UpdateDateColumn()
updated_at: Date;
}
Antworten:
Sie verwenden im Grunde eine
Adjacency list Tree
.Die Adjazenzliste ist ein einfaches Modell mit Selbstreferenzierung. Der Vorteil dieses Ansatzes ist die Einfachheit, ABER der Nachteil ist, dass Sie damit nicht mit tiefen Bäumen umgehen können.
Es gibt eine rekursive Möglichkeit, dies mit der Adjacency-Liste zu tun, aber es funktioniert nicht mit MySQL.
Die Lösung besteht darin, einen anderen Baumtyp zu verwenden. Andere mögliche Bäume sind:
Um einen Baum zu laden, verwenden Sie:
Nachdem Sie ein Baum-Repository erhalten haben, können Sie die nächsten Funktionen verwenden:
findTrees(), findRoots(), findDescendants(), findDescendantsTree()
und andere. Weitere Informationen finden Sie in der Dokumentation .Erfahren Sie mehr über verschiedene Baumarten: Modelle für hierarchische Daten
quelle
Wie Gabriel sagte, sind andere Datenmodelle besser, um die Leistung zu erbringen, die Sie möchten. Wenn Sie das Datenbankdesign nicht ändern können, können Sie Alternativen verwenden (die weniger performant oder hübsch sind, aber was in der Produktion funktioniert, ist am Ende alles, was zählt).
Wenn Sie den Lead-Wert in Ihrem LeadComment festlegen, kann ich vorschlagen, dass Sie diesen Wert auch für Antworten auf den Stammkommentar bei der Antworterstellung festlegen (sollte im Code einfach sein). Auf diese Weise können Sie alle Kommentare zu Ihrem Kunden in einer Abfrage abrufen (einschließlich der Antworten).
Natürlich müssen Sie einen SQL-Stapel ausführen, um die fehlenden Spaltenwerte zu füllen, aber es ist eine einmalige Sache, und sobald auch Ihre Codebasis gepatcht ist, müssen Sie danach nichts mehr ausführen. Und es ändert nichts an der Struktur Ihrer Datenbank (nur an der Art und Weise, wie Daten gefüllt werden).
Dann können Sie Nodejs das ganze Zeug (Listen der Antworten) einbauen. Um den "Root" -Kommentar zu erhalten, filtern Sie einfach nach Kommentaren, die keine Antworten sind (die keine Eltern haben). Wenn Sie nur die Stammkommentare aus der Datenbank möchten, können Sie die Abfrage sogar nur in diese ändern (mit parentComment null in der SQL-Spalte).
Dann können Sie Antworten auf die rootComments erhalten und die gesamte Liste rekursiv im Knoten erstellen.
Es gibt wahrscheinlich optimierte Möglichkeiten, diese Listen zu berechnen. Dies ist für mich eine der einfachsten, die gemacht werden können.
Abhängig von der Anzahl der Kommentare kann es langsam werden (Sie können die Ergebnisse beispielsweise durch Zeitstempel und Anzahl begrenzen, damit sie gut genug sind?). Achten Sie also darauf, dass Sie nicht das Universum der Kommentare zu einem "Justin Bieber" -Lead abrufen, der erhalten wird viele Kommentare ...
quelle