Deep populate mongoose module trong nodejs



  • Mình có 2 Schema như bên dưới

    var CommentSchema = new Schema({
        title : String ,
        replies : [{
            type : Schema.Types.ObjectId ,
            ref : 'Reply'
    });
    var ReplySchema = new Schema({
        body : String ,
        replies : [{
            type : Schema.Types.ObjectId ,
            ref : 'Reply'
        }]
    });
    

    Giờ mình query comment như sau :

    Comment.find({})
        .populate({
            path :'replies' ,
            populate : {
                path : 'replies'
            }
        }).exec(function(err , comment) {
         console.log(comment);
         });
    

    Mình làm theo hướng dẫn tại đây http://mongoosejs.com/docs/populate.html thì thấy dùng cách query trên sẽ populate đc 2 lần liên tiếp nhưng k hề được :| với bác nào có giải pháp về vấn đề populate N lần thì chia sẻ mình với . Mình có tìm kiếm một số cách thì thấy thường phải dùng module bên ngoài chứ không có giải pháp cụ thể



  • Bác nào đi qua giúp e chút :) chỉ cho e chỗ nhúng code trong giao diện viết bài với



  • Hi, bạn có thể viết chèn code theo cú pháp của markdown [1] nhé:

    // insert code javascript here
    

    [1]. https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code


  • The one love with javascript

    @kxd993 Mình không có nhiều kinh nghiệm với Mongoose nên chịu không trả lời được câu hỏi của bạn.

    Tuy nhiên có một vấn đề mà mình muốn chia sẻ với bạn:

    1. Bạn đang rơi vào trường hợp được gọi là N+1 query. Nó là vấn đề thường gặp khi bạn làm việc với các ORM như Mongoose. Đó là khi bạn phải thực hiện 1 truy vấn lấy N bản ghi, nhưng mỗi một bản ghi đó lại có tham chiếu đến 1 bản ghi nào khác nữa. Lỗi thường gặp của các bạn Developer là hay loop qua N bản ghi này và thực hiện thêm 1 truy vấn nữa trên từng bản ghi (trong trường hợp của bạn là thông qua hàm Populate), vậy là tổng cộng bạn phải thực thi N+1 câu truy vấn, thực tế, bạn chỉ cần thực hiện 2 câu truy vấn là đủ.

    2. Vì sao mình lại đưa vấn đề của RDBMS vào câu hỏi về NóQL của bạn? Vì mình đoán rằng bạn đang dùng NoSQL chưa đúng cách, bạn thử nghĩ xem có cách nào nest được cả reply vào trong comment không? Như vậy, bản thân cấu trúc document của bạn đã được nest rồi. Bye bye populate, bye bye N+1 query



  • @kdx993 Theo như mình biết thì api mongoose chỉ có thể giúp bạn populate được dữ liệu qua 1 lớp thôi, chứ không hỗ trợ bạn populate dữ liệu của dữ liệu đã được populate.

    Để làm được điều này bạn có thể npm install --save mongoose-deep-populate vào theo cách cài đặt trong trang https://github.com/buunguyen/mongoose-deep-populate

    Sau khi đã register plugin với CommentSchema bằng

    var deepPopulate = require('mongoose-deep-populate')
    CommentSchema.plugin(deepPopulate)
    

    và sau đó

    Comment.find()
      .deepPopulate('replies.replies')
      .exec(function(err, comments){
        console.log(comments)
    })
    

    Còn rất nhiều options để chỉnh bạn xem ở trang github của plugin nhé.



  • @rikky Thanks a , e cũng nghĩ đến vấn đề đó rồi . Nếu lưu như vậy thì sẽ có lợi cho việc select ra còn khi update lại thì sẽ mất công hơn . Nhưng do vấn đề comment ít khi được update thì e thấy giải pháp của a hợp lí hơn :D
    @jokyspy T cũng mới biết được module đó sau khi viết một đống method đệ quy để populate được :| lại còn phải giải quyết bất đồng bộ nữa , haizz đời k như mơ mà :D

    Cũng cảm ơn bác nào đi qua chỉnh sửa giúp bài viết hộ mình :dancer:


Log in to reply