2013-10-30 13 views
7

Mã sau hoạt động với không có truy vấn hoặc một chỉ chuỗi truy vấn. Nói cách khác, chỉ cần đi tới /characters trả về tất cả các ký tự. Nhưng nếu bạn chỉ định tham số chuỗi truy vấn /characters?gender=male, nó sẽ chỉ trả về các ký tự nam.Làm thế nào để xây dựng một truy vấn có điều kiện trong Mongoose?

Làm thế nào tôi có thể mở rộng này để làm việc với một trong hai , , , hoặc không querystrings? Tôi thực sự muốn tránh viết 8 hoặc 9 câu lệnh if khác nhau cho từng trường hợp. Tôi đã hy vọng Mongoose chỉ đơn giản là bỏ qua một điều khoản $ trong đó nếu đó là null hoặc undefined, nhưng đó không phải là trường hợp (xem nhận xét ra mã).

var gender = req.query.gender; 
    var race = req.query.race; 
    var bloodline = req.query.bloodline; 

    var query = Character.find(); 

    if (gender) 
    query = query.where('gender').equals(gender); 
    if (race) 
    query = query.where('race').equals(race); 
    if (bloodline) 
    query = query.where('bloodline').equals(bloodline); 

    /* 
    query 
    .where('gender').equals(new RegExp('^' + gender + '$', 'i')) 
    .where('race').equals(new RegExp('^' + race + '$', 'i')) 
    .where('bloodline').equals(new RegExp('^' + bloodline + '$', 'i')); 
    */ 

    query.exec(function(err, characters) { 
    if (err) throw err; 
    res.send(characters); 
    }); 

Edit: Vâng, tôi đoán tôi có thể làm điều đó với 7 if-báo cáo cho bây giờ. Trừ khi ai đó tìm thấy một giải pháp thanh lịch hơn.

Chỉnh sửa 2:

Thanks guys. Thật khó để chọn một câu trả lời vì cả hai bạn đã giúp tôi đạt được giải pháp ngắn gọn này. Đây là toàn bộ điều bây giờ.

var conditions = {}; 

for (var key in req.query) { 
    if (req.query.hasOwnProperty(key)) { 
    conditions[key] = new RegExp('^' + req.query[key] + '$', 'i'); 
    } 
} 

var query = Character.find(conditions); 
query.exec(function(err, characters) { 
    if (err) throw err; 
    res.send({ characters: characters }); 
}); 
+0

Không vấn đề gì, nhưng bạn nên chọn câu trả lời cho người dùng trong tương lai để biết điều gì giúp bạn nhiều hơn. Nếu bạn không thể, hãy suy nghĩ về cách viết câu trả lời của riêng bạn và kiểm tra câu trả lời đó là chính xác. – cschaeffler

+1

Bạn nên xóa Edit 2 của bạn và viết câu trả lời của riêng bạn, đó là tuyệt vời btw –

+0

Rất tốt đẹp - hoạt động tuyệt vời; ngoại trừ phần vệ sinh với RegEx tạo ra các truy vấn lạ. – nottinhill

Trả lời

10

Bạn không cần phải gọi Query#where lặp đi lặp lại, vì bạn có thể vượt qua tất cả các điều kiện để Mongoose Model#find như:

var filteredQuery = {}, 
    acceptableFields = ['gender', 'race', /* etc */ ]; 

acceptableFields.forEach(function(field) { 
    req.query[field] && filteredQuery[field] = req.query[field]; 
}); 

var query = Character.find(filteredQuery); 

Bạn cũng sẽ muốn để khử trùng req.query tùy thuộc vào các thông số cho phép bạn có trong tâm trí.

2

Vâng,

Tôi muốn giới thiệu một cái gì đó như thế này:

var query = Character.find() 
if(req.params.length < 0) { 
    for(var key in req.params) { 
    query.where(req.params[key]).equals(key); 
    } 
} else { 
    // do something without query params 
} 

này không được thử nghiệm bởi tôi nhưng nó cũng làm việc (có thể bạn cần phải sửa đổi nó một chút nhưng bạn sẽ có được ý tưởng). Giải pháp này là tất cả về việc không kiểm tra những gì thực sự là trong params vì vậy hãy chắc chắn chỉ có công cụ tốt đến hoặc xác nhận nó một nơi nào đó trong vòng lặp, nhưng sẽ yêu cầu một số regex hoặc nếu báo cáo.

Hy vọng điều này sẽ giúp bạn.

+0

** Dành cho khách truy cập trong tương lai **: Ví dụ của câu trả lời được chấp nhận không hoạt động. Tôi thậm chí không sử dụng req.params, mà là req.query. Thay vì chuỗi '.where', tôi đang xây dựng một đối tượng * condition * động và sau đó truyền nó tới' Character.find() '. Tham khảo Chỉnh sửa số 2 của tôi. –

Các vấn đề liên quan