Tại sao bạn không thể sửa đổi dữ liệu được trả về bởi Truy vấn Mongoose (ví dụ: findById)


94

Khi tôi cố gắng thay đổi bất kỳ phần nào của dữ liệu được trả về bởi Mongoose Query, điều đó không có tác dụng.

Tôi đã cố gắng tìm ra điều này trong khoảng 2 giờ ngày hôm qua, với tất cả các loại _.clone()s, sử dụng các biến lưu trữ tạm thời, v.v. Cuối cùng, ngay khi tôi đang phát điên, tôi đã tìm ra giải pháp. Vì vậy, tôi đã tìm ra ai đó trong tương lai (fyuuuture!) Có thể gặp sự cố lưu.

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


bản sao có thể có của stackoverflow.com/q/9952649/4748042
martinho

Câu trả lời:


160

Đối với những trường hợp như thế này khi bạn muốn một đối tượng JS thuần túy thay vì một phiên bản mô hình đầy đủ, bạn có thể gọi lean()chuỗi truy vấn như sau:

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

Cách datanày đã là một đối tượng JS đơn giản mà bạn có thể thao tác khi cần.


8
Btw @JohnnyHK chỉ muốn nói lời cảm ơn một lần nữa. Một năm rưỡi sau đó đã giúp một khách hàng gỡ lỗi một cái gì đó. Ông đã dành một ngày cuối tuần cố gắng để hình một cái gì đó, lần lượt ra đó là vì ông đã cố gắng để thay đổi Object Mongoose; P
toli

1
2 năm sau và vẫn nghiền nó. Thậm chí không nhận ra nạc () ở đó.
Petrogad

1
@Fizzix aggregateluôn cung cấp kết quả của nó dưới dạng các đối tượng đơn giản, vì vậy không cần thiết lean().
JohnnyHK

1
3 năm sau và dành cả giờ đồng hồ để tìm ra nó. Đã lưu cả ngày của tôi! Cảm ơn
Noy

2
Cảm ơn bạn! Điều này thực sự hữu ích, nhưng tại sao không thể sửa đổi đối tượng? Đó là loại vật thể đặc biệt nào?
Robert Fedus

46

Tôi nghĩ rằng tài liệu Mongoose không làm cho điều này đủ rõ ràng, nhưng dữ liệu được trả lại trong truy vấn (mặc dù bạn có thể gửi lại () nó) thực sự là một đối tượng Tài liệu Mongoose và KHÔNG PHẢI là một đối tượng JSON. Nhưng bạn có thể khắc phục điều này bằng một dòng ...

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
Bạn cũng có thể sử dụng toObject(), thực hiện điều tương tự toJSON()nhưng với một tên ít khó hiểu hơn.
JohnnyHK

1
Điều này cũng sẽ loại bỏ các ảo do nhà phát triển đưa vào?
mjwrazor 14/09/2016

5
TypeError: data.toObject is not a functionTôi nhận được cái này, cùng vớitoJSON
Luzan Baral

Thay vì sửa đổi result, tôi đã có thể sửa đổi result._doc.
nth-chile

@Luzan Baral Thats vì bạn đang sử dụng hàm này cho đối tượng Array. Sử dụng JSON.parse(JSON.stringify(data))thay thế cho Mảng đối tượng
mohit
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.