নেস্টজেএস নোডেজ সম্পর্কের সাথে এক প্রশ্নের মধ্যে নেস্টেড মন্তব্যগুলি লোড করে?


10

আমার কাছে নিম্নলিখিত মডেলগুলি রয়েছে:

User, Customer,Comment

ব্যবহারকারী Customerএকটিতে মন্তব্য করতে পারে, ব্যবহারকারী অন্য ব্যবহারকারীর মন্তব্যে জবাব দিতে পারে, পুনরাবৃত্তিমূলকভাবে সীমাহীন।

আমি এটি করেছি তবে এটি কেবলমাত্র একটি জবাবের মধ্যে সীমাবদ্ধ এবং আমি সমস্ত উত্তর পেতে চাই:

public async getCommentsForCustomerId(customerId: string): Promise<CustomerComment[]> {
    return this.find({where: {customer: {id: customerId}, parentComment: null}, relations: ['childComments']});
}

তবে আমি যে প্রতিক্রিয়া পাচ্ছি তা কেবলমাত্র এক স্তরে নেস্ট করা হয়েছে:

[
    {
        "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"
            }
        ]
    }
]

আমি কীভাবে এই সমস্তগুলিকে টাইপরমে বাসাতে পারি?

সত্তা সংজ্ঞা (নোট গ্রাহকের নাম পরিবর্তিত হয়েছে নেতৃত্ব) :

@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;
}

1
আপনি কি আপনার সত্তার সংজ্ঞা যুক্ত করতে পারেন?
জেনবেেনি

@ জেনবেেনি যোগ করেছেন ধন্যবাদ
বেন বেরি

উত্তর:


7

আপনি মূলত একটি ব্যবহার করছেন Adjacency list Tree

অ্যাডজেসেন্সি তালিকা স্ব-উল্লেখের সাথে একটি সহজ মডেল। এই পদ্ধতির সুবিধা হ'ল সরলতা, তবে অসুবিধাটি হ'ল আপনি গভীর গাছগুলি এটির সাথে পরিচালনা করতে পারবেন না।

অ্যাডজেসেন্সি তালিকার সাথে এটি করার একটি পুনরাবৃত্ত উপায় আছে তবে এটি মাইএসকিউএল নিয়ে কাজ করে না।

সমাধানটি অন্য ধরণের গাছ ব্যবহার করা। অন্যান্য সম্ভাব্য গাছগুলি হ'ল:

  • নেস্টেড সেট : এটি পড়ার জন্য খুব দক্ষ, তবে লেখকের পক্ষে খারাপ। নেস্টেড সেটে আপনার একাধিক শিকড় থাকতে পারে না।
  • মেটেরিয়ালাইজড পাথ : (পাথ এনুমারেশনও বলা হয়) সহজ এবং কার্যকর।
  • বন্ধ সারণী : পিতামাতার এবং সন্তানের মধ্যে সম্পর্ক আলাদা টেবিলে সঞ্চয় করে। উভয়ই পড়তে এবং লেখায় দক্ষ (কোনও উপাদানটির পিতামাতার আপডেট করা বা অপসারণ এখনও কার্যকর করা হয়নি)
@Entity()
@Tree("nested-set") // or @Tree("materialized-path") or @Tree("closure-table")
export class Category {

    @PrimaryGeneratedColumn()
    id: number;

    @TreeChildren()
    children: Category[];

    @TreeParent()
    parent: Category;
}

একটি গাছ ব্যবহার লোড করতে:

const manager = getManager();
const trees = await manager.getTreeRepository(Category).findTrees();

আপনি গাছের সংগ্রহস্থল পাওয়ার পরে, আপনি পরবর্তী ফাংশনগুলি: findTrees(), findRoots(), findDescendants(), findDescendantsTree()এবং অন্যান্য ব্যবহার করতে পারেন । আরও জন্য ডকুমেন্টেশন দেখুন।

বিভিন্ন ধরণের গাছ সম্পর্কে আরও জানুন: শ্রেণিবদ্ধ তথ্যের জন্য মডেল


1

গ্যাব্রিয়েল যেমন বলেছিলেন, অন্যান্য পারফরম্যান্স মডেলগুলি যা পারফরম্যান্স অনুযায়ী আপনি চান তা করা আরও ভাল। তবুও যদি আপনি ডাটাবেস ডিজাইনটি পরিবর্তন করতে না পারেন তবে আপনি বিকল্পগুলি ব্যবহার করতে পারেন (যা কম পারফরম্যান্ট বা চমত্কার, তবে উত্পাদনে যা কাজ করে তা শেষ পর্যন্ত গুরুত্বপূর্ণ)।

আপনি আপনার লিডকমেন্টে শীর্ষস্থান নির্ধারণ করার সময়, আমি প্রস্তাব দিতে পারি যে আপনি উত্তরটি তৈরির মূল মন্তব্যে জবাবগুলিতেও এই মানটি সেট করুন (কোডে সহজ হওয়া উচিত)। এইভাবে আপনি আপনার প্রশ্নের সাথে আপনার গ্রাহকের সমস্ত মন্তব্য একটি ক্যোয়ারিতে (উত্তরগুলি সহ) পেতে পারেন।

const lead = await leadRepository.findOne(id);
const comments = await commentRepository.find({lead});

অবশ্যই, অনুপস্থিত কলাম মানগুলি পপুলেট করতে আপনাকে একটি এসকিউএল ব্যাচ চালাতে হবে, তবে এটি এক সময়ের জিনিস এবং আপনার কোডবেসটি প্যাচ করার পরে আপনাকে আর কিছু চালাতে হবে না। এবং এটি আপনার ডাটাবেসের কাঠামো পরিবর্তন করে না (কেবলমাত্র ডেটা জনবহুল হয়)।

তারপরে আপনি নোডেজে পুরো জিনিস তৈরি করতে পারবেন (জবাবগুলির তালিকা)। "মূল" মন্তব্যটি পেতে, কেবলমাত্র এমন মন্তব্য দ্বারা ফিল্টার করুন যা উত্তর নয় (যার পিতামাতারা নেই)। আপনি যদি কেবল ডাটাবেস থেকে মূল মন্তব্যগুলি চান তবে আপনি ক্যোয়ারীটি কেবলমাত্র এইগুলিতে পরিবর্তন করতে পারেন (এসকিউএল কলামে প্যারেন্টকমেন্ট নাল সাথে)।

function sortComment(c1: LeadComment , c2: LeadComment ): number {
    if (c1.created_at.getTime() > c2.created_at.getTime()) {
    return 1;
    }
    if (c1.created_at.getTime() < c2.created_at.getTime()) {
        return -1;
    }
    return 0;
}
const rootComments = comments
    .filter(c => !c.parentComment)
    .sort(sortComment);

তারপরে আপনি রুট কমেন্টে জবাব পেতে পারেন এবং নোডে পুনরাবৃত্তভাবে পুরো তালিকা তৈরি করতে পারেন।

function buildCommentList(currentList: LeadComment[], allComments: LeadComment[]): LeadComment[] {
    const lastComment = currentList[currentList.length - 1];
    const childComments = allComments
        .filter(c => c.parentComment?.id === lastComment.id)
        .sort(sortComment);
    if (childComments.length === 0) {
        return currentList;
    }
    const childLists = childComments.flatMap(c => buildCommentList([c], allComments));
    return [...currentList, ...childLists];
}

const listsOfComments = rootComments.map(r => buildCommentList([r], comments));

এই তালিকাগুলি গণনা করার জন্য আরও আরও অনুকূলিত উপায় রয়েছে, এটি আমার পক্ষে তৈরি করা যায় এমন সহজতম একটি।

মন্তব্যের সংখ্যার উপর নির্ভর করে এটি ধীর হয়ে যেতে পারে (উদাহরণস্বরূপ আপনি টাইমস্ট্যাম্প এবং সংখ্যা অনুসারে ফলাফল সীমাবদ্ধ করতে পারেন যাতে এটি যথেষ্ট ভাল হওয়া উচিত?) তাই সাবধান হন, "জাস্টিন বিবার" লিডের মন্তব্যে মহাবিশ্বকে আনাবেন না যা পান অনেক মন্তব্য ...

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.