เหตุใดคุณจึงไม่สามารถแก้ไขข้อมูลที่ส่งคืนโดย Mongoose Query (เช่น findById)


95

เมื่อฉันพยายามเปลี่ยนส่วนใดส่วนหนึ่งของข้อมูลที่ส่งคืนโดย Mongoose Query ก็ไม่มีผลใด ๆ

เมื่อวานนี้ฉันพยายามคิดออกมาประมาณ 2 ชั่วโมงโดยมี_.clone()s ทุกชนิดโดยใช้ตัวแปรพื้นที่จัดเก็บชั่วคราว ฯลฯ ในที่สุดเมื่อฉันกำลังจะบ้าฉันก็พบวิธีแก้ปัญหา ฉันจึงคิดว่ามีใครบางคนในอนาคต (fyuuuture!) อาจมีปัญหาในการบันทึก

Survey.findById(req.params.id, function(err, data){
    var len = data.survey_questions.length;
    var counter = 0;

    _.each(data.survey_questions, function(sq){
        Question.findById(sq.question, function(err, q){
            sq.question = q; //has no effect

            if(++counter == len) {
                res.send(data);
            }
        });
    });
});


สามารถทำซ้ำได้ของstackoverflow.com/q/9952649/4748042
martinho

คำตอบ:


163

สำหรับกรณีเช่นนี้ที่คุณต้องการออบเจ็กต์ JS ธรรมดาแทนที่จะเป็นอินสแตนซ์แบบเต็มคุณสามารถเรียกlean()ใช้คิวรีเชนดังนี้:

Survey.findById(req.params.id).lean().exec(function(err, data){
    var len = data.survey_questions.length;
    var counter = 0;

    _.each(data.survey_questions, function(sq){
        Question.findById(sq.question, function(err, q){
            sq.question = q;

            if(++counter == len) {
                res.send(data);
            }
        });
    });
});

วิธีdataนี้เป็นออบเจ็กต์ JS ธรรมดาอยู่แล้วที่คุณสามารถจัดการได้ตามต้องการ


9
Btw @JohnnyHK แค่อยากจะขอบคุณอีกครั้ง หนึ่งปีครึ่งต่อมากำลังช่วยลูกค้าแก้ไขข้อบกพร่องบางอย่าง เขาใช้เวลาสุดสัปดาห์ในการพยายามคิดอะไรบางอย่างปรากฎว่าเป็นเพราะเขาพยายามปรับเปลี่ยน Mongoose Object P
Toli

1
2 ปีต่อมาและยังคงบดขยี้มัน ไม่รู้ด้วยซ้ำว่ามีลีน () อยู่ที่นั่น
Petrogad

1
@Fizzix เสมอให้ผลของมันเป็นวัตถุธรรมดาจึงไม่มีความจำเป็นในการaggregate lean()
JohnnyHK

1
3 ปีต่อมาและใช้เวลาทั้งชั่วโมงในการพยายามคิดออก บันทึกทั้งวันของฉัน! ขอบคุณ
Noy

2
ขอขอบคุณ! สิ่งนี้ช่วยได้มาก แต่เหตุใดจึงไม่สามารถแก้ไขวัตถุได้ เป็นวัตถุพิเศษชนิดใด?
Robert Feduș

46

ฉันคิดว่าเอกสาร Mongoose ไม่ได้ทำให้ชัดเจนเพียงพอ แต่ข้อมูลที่ส่งคืนในแบบสอบถาม (แม้ว่าคุณสามารถ res.send () ได้) เป็นวัตถุพังพอนและไม่ใช่วัตถุ JSON แต่คุณสามารถแก้ไขได้ด้วยบรรทัดเดียว ...

Survey.findById(req.params.id, function(err, data){
    var len = data.survey_questions.length;
    var counter = 0;

    var data = data.toJSON(); //turns it into JSON YAY!

    _.each(data.survey_questions, function(sq){
        Question.findById(sq.question, function(err, q){
            sq.question = q;

            if(++counter == len) {
                res.send(data);
            }
        });
    });
});

12
คุณยังสามารถใช้toObject()ซึ่งทำเช่นเดียวtoJSON()กับชื่อที่สับสนน้อยกว่า
JohnnyHK

2
สิ่งนี้จะกำจัด Virtuals ที่นักพัฒนาใส่ไว้ด้วยหรือไม่?
mjwrazor

5
TypeError: data.toObject is not a functionฉันได้รับสิ่งนี้เช่นเดียวกับtoJSON
Luzan Baral

แทนที่จะแก้ไขresultฉันสามารถแก้ไขresult._docไฟล์.
n-chile

@ Luzan Baral นั่นเพราะคุณใช้ฟังก์ชันเหล่านี้สำหรับวัตถุ Array ใช้JSON.parse(JSON.stringify(data))แทน Arrays of object
mohit
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.