2014-04-12 16 views
6

Tôi đang triển khai cách để người dùng thay đổi tên người dùng của họ trong ứng dụng Meteor mà tôi đang viết. Trước khi chấp nhận thay đổi, tôi muốn kiểm tra xem tên người dùng đã tồn tại chưa. Tên người dùng có thể chứa chữ hoa và chữ thường, nhưng chúng phải là tên duy nhất bất kể chữ hoa chữ thường. Ví dụ: bobBob không thể tồn tại cùng nhau.Meteor: Làm thế nào để làm một trường hợp không nhạy cảm collection.findOne()?

Vấn đề là tôi dường như không thể tìm ra cách thực hiện một số collection.findOne() không phân biệt chữ hoa chữ thường. Ví dụ, nói rằng tôi có một bộ sưu tập được gọi là Profiles, tôi muốn để có thể làm điều gì đó như thế này:

newName = "bob"; 

//Assume "Bob" exists as a username in the Profiles collection; 

var isAlreadyRegistered = Profiles.findOne({"username": newName}); 

if (isAlreadyRegistered == null) { 
    saveUsername(); 
}; 

Trả lời

12

bạn có thể sử dụng regular expression.

var isAlreadyRegistered = Profiles.findOne({"username": /^newName$/i }); 

Hoặc bạn có thể truy vấn như cũng này:

var isAlreadyRegistered = Profiles.findOne({ "username" : { 
        $regex : new RegExp(newName, "i") } } 
       ); 
+1

Câu trả lời hay, nhưng tôi tự hỏi tại sao ví dụ đầu tiên của bạn không hoạt động đối với tôi trong khi ví dụ thứ hai không hoạt động. – adrianmc

2

có hai cách và mileage của bạn có thể thay đổi về phương pháp tốt nhất cho bạn, nhưng cả hai đều khá khủng khiếp thực sự kể từ khi MongoDB không trường hợp "nhạy cảm" phù hợp:

phương pháp đầu tiên là sử dụng $regex:

Profiles.findOne({ "username": { 
    "$regex": "^" + newName + "\\b", "$options": "i" 
}}) 

Đó phù hợp với lời nói và chỉ chính xác từ từ bắt đầu của chuỗi trong một trường hợp cách vô cảm. Vấn đề ở đây là bạn đang quét chỉ mục.

Cách tiếp cận thứ hai là dự án sử dụng tổng hợp:

db.collection("profiles").aggregate([ 
    { "$project": { 
     "username": 1, 
     "lower": { "$toLower": "$username" } 
    }}, 
    { "$match": { 
     "username": newName 
    }} 
]) 

Và bạn làm điều đó mà dĩ nhiên newName đã được chuyển đổi sang chữ thường.

Vấn đề ở đây là $project trên mọi thứ trong đường ống. Nhưng có thể hữu ích nếu bạn có thể $match trước tiên.

Tất nhiên tôi nghĩ rằng aggregate chỉ khả dụng ở phía máy chủ chứ không phải thông qua Minimongo, vì vậy cần xem xét.

+0

Tôi tin rằng tôi đã nói điều đó và cũng tuyên bố rằng có thể sử dụng điều này trên máy chủ bên trong phương pháp của riêng bạn. –

+0

@AndrewMao vì lợi ích của tất cả độc giả và chính bạn, tuyên bố đó là sai.Tất cả các triển khai khung công tác tại một số điểm sử dụng và cho phép truy cập vào trình điều khiển cơ bản và các phương thức của nó, do đó, bằng cách lấy đối tượng bộ sưu tập gốc, bạn luôn có thể có được phương thức này, và cũng như hầu hết các khung công tác cung cấp ít nhất một giao diện cho "runCommand" trong một số hình thức nó cũng có thể được thực hiện theo cách này. Tất cả các phương thức MongoDB trong trình điều khiển đều được thực hiện theo cách này. Vì vậy, bất kể cú pháp gọi điện thoại, bạn không nên nói rằng nó id không có sẵn. –

1

Là giải pháp cho trường hợp sử dụng cơ bản của bạn, tôi khuyên bạn nên sử dụng hai trường để lưu trữ tên người dùng thay vì một.

Trường tên người dùng được tích hợp nên lưu trữ phiên bản chữ thường của tên người dùng. Trường khác, trường bổ sung lưu trữ phiên bản phân biệt chữ hoa chữ thường.

Tìm kiếm sẽ được tiến hành đối với trường 'tên người dùng' với tiêu chí tìm kiếm được giảm xuống trước khi sử dụng.

+0

Theo tiền đề chung của những gì ** nên ** được thực hiện. Bạn rất đúng trong đó cần phải có một lĩnh vực mà thực sự có giá trị chữ thường trong tài liệu và lập chỉ mục. Nhưng các tùy chọn khác chỉ tồn tại như thể hiện rằng thực sự có ** cách để làm điều này, và thậm chí là "trên bay" thường bị bỏ qua. –

+1

Vâng, đây là một trong những trường hợp thú vị mà câu hỏi đặt ra là có câu trả lời hay nhưng thực tế tốt nhất để giải quyết vấn đề cơ bản không thực sự được hỏi. – alanning

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