2012-01-12 31 views
19

Tôi có một bộ sưu tập người dùng, mỗi người trong số đó có thể được đăng ký một hoặc nhiều dịch vụ. Mỗi dịch vụ có một số dữ liệu meta, bao gồm số lượng tín dụng mà người dùng có cho dịch vụ đó.Ký tự đại diện dấu chấm Mongodb dot?

Làm cách nào để tìm tất cả các đối tượng người dùng có dưới 50 tín dụng cho một số dịch vụ nếu tôi không biết cách nào các khóa đối tượng dịch vụ sẽ là gì?

Về mặt lý thuyết, nó sẽ là một cái gì đó như thế này, mà không làm việc:

db.users.find({services.*.credits : {$lt : 50}}) 

Bộ sưu tập người dùng:

{ 
_id: 4f0ea25072139e4d2000001f, 
services : { 
    a : { credits : 100, score : 2000 }, 
    b : { credits : 200, score : 300 }, 
    c : { credits : 10, score : 1300 } 
    } 
}, 
{ 
_id: 4f0ea25072139e4d2000001f, 
services : { 
    f : { credits : 68, score : 14 }, 
    q : { credits : 1000, score : 102 }, 
    z : { credits : 59, score : 352 } 
    } 
} 

Một ví dụ về những gì tôi muốn làm, trong trường hợp nó không phải rõ ràng ở đây, được giải thích tại đây: http://www.mongodb.org/display/DOCS/Advanced+Queries#comment-346075854

Trả lời

-1

Tôi nghĩ sẽ dễ dàng hơn nếu bạn đặt đối tượng dịch vụ đó thành mảng, vì vậy bạn có thể sử dụng $elemMatch, như:

{ 
    services : [ 
    {key: "a" , credits : 100, score : 2000 }, 
    {key: "b", credits : 200, score : 300 }, 
    {key: "c", credits : 10, score : 1300 } 
    ] 
} 

{ 
    _id: 4f0ea25072139e4d2000001f, 
    services : [ 
    {key: "f", credits : 68, score : 14 }, 
    {key: "q", credits : 1000, score : 102 }, 
    {key: "z", credits : 59, score : 352 } 
    ] 
} 

Sau đó truy vấn mà bạn sẽ viết sẽ là như thế này:

db.coll.find({services: {$elemMatch : {credits: {$lt: 50}}}}); 

kết quả:

{ "_id" : ObjectId("4f0f2be07561bf94ea47eec4"), "services" : [ { "key" : "a", "credits" : 100, "score" : 2000 }, { "key" : "b", "credits" : 200, "score" : 300 }, { "key" : "c", "credits" : 10,  "score" : 1300 } ] } 
+0

tôi đã kết thúc thay đổi schema của chúng tôi chỉ sử dụng một mảng. Tôi có thể đã sử dụng $ elemMatch, nhưng vì tôi chỉ cần khớp với một tiêu chí duy nhất, tôi có thể làm: 'db.users.find ({services.credits: {$ lt: 50}})' – stuporglue

+9

-1 vì đây không phải là câu trả lời cho câu hỏi. Không phải ai cũng có khả năng thay đổi lược đồ dữ liệu mà họ đang làm việc. Câu hỏi này vẫn chưa được trả lời. – CommaToast

+0

OK Tôi tự trả lời. Tìm thấy một cách để làm điều đó. Đăng dưới đây. – CommaToast

1

tôi không biết cách để thực hiện điều này bằng cách sử dụng lược đồ you'r e sử dụng. Dường như với tôi bạn đang lạm dụng các đối tượng như mảng. Nếu services là một mảng (các gợi ý số nhiều rằng nó nên được), bạn chỉ có thể truy vấn

db.users.find({"services.credits" : { $lt : 50 }}); 

hoặc sử dụng $elemMatch nếu bạn cần phải kết hợp nhiều điều kiện về một phần tử mảng duy nhất.

+0

Điều tôi thực sự muốn là mảng kết hợp, điều này sẽ ngăn cản tôi có hai phần tử mảng cho cùng một id dịch vụ. Người dùng của chúng ta không bao giờ nên kết thúc với '{services: [{service: f, credits 50}, {service: f, credits: 60}]}'. Một mảng kết hợp thực thi điều này và làm cho 90% số lần tra cứu của chúng tôi tầm thường. Sử dụng các mảng thông thường buộc tôi phải tìm kiếm mảng trước khi thực hiện các truy vấn để xem liệu tôi có cần thêm mảng dịch vụ hay tìm một phần tử và cập nhật nó hay không. – stuporglue

+0

Hầu hết các kiểm tra tính nhất quán phải được thực hiện bằng mã. Điều đó cũng đúng đối với mảng kết hợp.MongoDB không hỗ trợ các ràng buộc trong các tài liệu nhúng: http://waistcode.net/blog/unique-array-keys-in-mongodb, tức là một đối tượng không thể 'vi phạm chính nó'. – mnemosyn

+0

Đây không phải là câu trả lời cho câu hỏi. Lời bình luận của @ stuporglue ở trên giải thích một lý do hoàn toàn hợp lệ và tuyệt vời để tạo ra mô hình dữ liệu của anh ấy theo cách anh ấy đã làm. Đó là lý do giống như mô hình dữ liệu của chúng tôi đã được thực hiện theo cách chúng tôi đã làm nó. Và tôi vẫn cần câu trả lời cho câu hỏi này. Mọi người nói rằng họ không biết câu trả lời, hoặc cáo buộc những người lạm dụng mọi thứ, vv, chỉ là không hiệu quả. – CommaToast

15

Đây là câu trả lời thực tế cho câu hỏi của bạn.

Cách bạn có thể tìm thấy tất cả các đối tượng người dùng có ít hơn 50 tín dụng cho một số dịch vụ nếu bạn không biết cách nào các khóa đối tượng dịch vụ sẽ như sau.

Sử dụng $ nơi truy vấn:

db.users.find({ 
    $where: function() { 
     for (var index in this.services) 
      if (this.services[index].credits < 50) 
       return this; 
    } 
}); 
+1

'Truy vấn' của bạn thiếu hỗ trợ chỉ mục hoàn toàn. Không có lý do gì để sử dụng cấu trúc dữ liệu như thế này; nếu bạn thậm chí không thể mô phỏng một chỉ mục, bạn đang thực hiện quét bộ sưu tập mỗi lần và bạn cũng có thể tải toàn bộ bộ sưu tập trong RAM và quét nó ở đó, sau đó là một bài tập nhỏ trong JavaScript. – mnemosyn

+7

Ông hỏi, "Làm thế nào tôi có thể tìm thấy tất cả các đối tượng người dùng có ít hơn 50 tín dụng cho một số dịch vụ nếu tôi không có cách nào biết được các khóa đối tượng dịch vụ sẽ là gì?" Tôi trả lời câu hỏi của anh ấy. Tôi không downvote "người trả lời" chỉ là câu trả lời, bởi vì họ không phải là câu trả lời. Họ là những người nói, "Bạn không thể/không nên làm điều đó" khi rõ ràng bạn có thể, và nó hoàn toàn là một vấn đề của ý kiến ​​về việc liệu bạn nên. Tôi không đồng ý rằng "không có lý do gì để sử dụng cấu trúc dữ liệu như thế này" ... có rất nhiều lý do tuyệt vời để làm như vậy. Chỉ vì bạn không biết chúng, không thực sự là lỗi của tôi cũng không phải của op. – CommaToast

+4

Tôi không nhìn vào đại diện của người dân tôi chỉ đọc câu trả lời. Tôi không nghi ngờ rằng bạn biết thêm về MongoDB hơn tôi. Nhưng nếu đó không phải là câu trả lời cho câu hỏi đã được hỏi thì tôi buộc phải từ chối nó; Tôi sẽ không làm như vậy đơn giản bởi vì bạn có một đại diện cao. Nói với ai đó không có cách nào để làm điều gì đó, khi thực tế có, không phải là mát mẻ. Nói với mọi người rằng cấu trúc dữ liệu của họ là vô nghĩa chỉ vì bạn không nhìn thấy điểm của nó, cũng không phải là mát mẻ. Có lẽ họ có một lý do tuyệt vời để sử dụng nó mà bạn chỉ đơn giản là không hiểu. Có lẽ nếu bạn hỏi bạn có thể học được điểm nào. – CommaToast

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