2013-06-25 50 views
32

Tôi đã hỏi đây là nhận xét về câu hỏi another và cũng đã đăng một question trên người dùng mongodb. Không có câu trả lời cho đến nay, vì vậy tôi đang sử dụng để đặt câu hỏi riêng.MongoDB truy vấn mảng lồng nhau

Các documentation trạng thái:

Nếu trường có chứa một mảng, thì $ trong khai thác chọn tài liệu mà lĩnh vực giữ một mảng có chứa ít nhất một yếu tố phù hợp với một giá trị trong mảng được chỉ định (ví dụ: vv)

tôi đang sử dụng:

mongod --version: 
db version v2.2.2, pdfile version 4.5 
Thu May 30 12:19:12 git version: d1b43b61a5308c4ad0679d34b262c5af9d664267 

mongo --version: 
MongoDB shell version: 2.0.4 

Trong MongoDB shell:

db.nested.insert({'level1': {'level2': [['item00', 'item01'], ['item10', 'item11']]}}) 

Dưới đây là một danh sách các truy vấn mà nên làm việc theo các tài liệu, và kết quả họ sản xuất:

Tại sao không làm việc này?

> db.nested.findOne({'level1.level2.0': 'item00'}) 
null 

Tại sao tôi cần $ tất cả?

> db.nested.findOne({'level1.level2.0': {'$all': ['item00']}}) 
{ 
    "_id" : ObjectId("51a7a4c0909dfd8872f52ed7"), 
    "level1" : { 
     "level2" : [ 
      [ 
       "item00", 
       "item01" 
      ], 
      [ 
       "item10", 
       "item11" 
      ] 
     ] 
    } 
} 

Ít nhất một trong những điều sau đây sẽ hiệu quả, phải không?

> db.nested.findOne({'level1.level2.0': {'$in': ['item00']}}) 
null 

> db.nested.findOne({'level1.level2': {'$in': ['item00']}}) 
null 

Bất kỳ ý tưởng nào? Chúng tôi đang xem xét việc bỏ MongoDB nếu cú ​​pháp truy vấn không hoạt động như được quảng cáo.

Cảm ơn!

Trả lời

6

Sử dụng lồng nhau elemMatch để tìm kiếm các cấp lồng nhau trong các mảng.

Chi tiết here.

4

Câu trả lời ngắn: $ in dành cho trường giá trị đơn và $ tất cả là dành cho mảng.

Đầu tiên, db.nested.findOne({'level1.level2.0': 'item00'}) không hoạt động vì level1.level2.0 giữ một mảng và bạn đang cố gắng so sánh nó với một giá trị duy nhất.

Hiện tại, db.nested.findOne({'level1.level2.0': {'$in': ['item00']}}) không hoạt động vì lý do tương tự. $ in là để so sánh một trường với một giá trị duy nhất (bạn có một mảng) với một vài giá trị trong một mảng (được chỉ rõ trong truy vấn). $ trong đang nói: cho tôi các tài liệu có trường này có giá trị được bao gồm trong mảng này.

$ tất cả đang hoạt động bởi vì nó cho biết: cung cấp cho tôi các tài liệu có trường này với nhiều giá trị và tất cả các giá trị của mảng này (trong truy vấn) được bao gồm trong trường đó. (chỉnh sửa)

Có thể là khó khăn để có được nhưng nhìn vào những gì các tài liệu nói cho mỗi:

$ tất cả các lựa chọn tài liệu nơi lĩnh vực này nắm giữ một mảng và chứa tất cả các yếu tố(e.g. <value>, <value1>, etc.) trong mảng.

$ trong lựa chọn tài liệu có giá trị lĩnh vực tương đương với bất kỳ giá trị trong mảng quy định (e.g. <value1>, <value2>, etc.)

Hy vọng nó giúp

+0

Đánh giá cao việc bạn dành thời gian trả lời, nhưng rất tiếc, không có câu trả lời nào của bạn là chính xác. Trong trang "Đọc" của hướng dẫn sử dụng, tìm kiếm "Thao tác sau trả về một con trỏ tới tất cả các tài liệu trong bộ sưu tập bios, trong đó các trường tham chiếu mảng chứa phần tử 'UNIX':" Trong liên kết tài liệu gần đầu câu hỏi của tôi, bạn có thể thấy rằng $ in nên hoạt động trên các trường có chứa mảng. Cuối cùng, câu lệnh của bạn "$ all đang hoạt động vì ..." là sai: không phải tất cả các giá trị trong trường cần tồn tại trong truy vấn, nhưng tất cả các giá trị trong truy vấn phải tồn tại trong trường của tài liệu. – dgorur

+0

Cảm ơn bạn đã sửa "$ tất cả đang hoạt động vì ...". Vì vậy, bạn đang nói rằng $ trong nên làm việc cho mảng và tài liệu nói như vậy. Bây giờ tôi bị hấp dẫn. Tôi sẽ thực hiện một số thí nghiệm và xem liệu tôi có tìm ra không. Bạn có một câu hỏi rất thú vị ở đây! – AntonioOtero

+0

Tôi đưa những phát hiện của mình vào một câu trả lời khác, tôi hy vọng nó hữu ích cho bạn. – AntonioOtero

29

Sau khi chạy một số truy vấn, tôi đi đến kết luận rằng $ in không hoạt động đối với mảng mảng.

Bạn có thể sử dụng $elemMatch thay vào đó và nó sẽ hoạt động, nhưng thật khó chịu khi tài liệu của MongoDB không cảnh báo về nó.

Tôi tạo ra tài liệu này:

{ 
     "_id": "51cb12857124a215940cf2d4", 
     "level1": [ 
     [ 
      "item00", 
      "item01" 
     ], 
     [ 
      "item10", 
      "item11" 
     ] 
     ], 
     "items": [ 
     "item20", 
     "item21" 
     ] 
} 

Chú ý rằng trường "mặt hàng" là một mảng của chuỗi và truy vấn này hoạt động hoàn hảo:

db.nested.findOne({"items":{"$in":["item20"]} }) 

Bây giờ, "level1.0" cũng là một chuỗi các chuỗi, sự khác biệt duy nhất là nó nằm bên trong một mảng khác. Truy vấn này nên làm việc nhưng không phải là:

db.nested.findOne({"level1.0":{"$in":["item00"]} }) 

Cách duy nhất để có được kết quả được sử dụng $ elemMatch:

db.nested.findOne({"level1":{"$elemMatch":{"$in":['item00']}} }) 

Vì vậy $elemMatch giải quyết vấn đề, nhưng là giải pháp thực sự là để cập nhật tài liệu MongoDB của để nói rằng $in không hoạt động đối với mảng mảng. Có lẽ bạn nên gửi yêu cầu tới 10gen.

+1

Hehe. Bây giờ bạn đang nói chuyện. Tôi đã sử dụng giải pháp này cho một số truy vấn, nhưng sau đó: nếu tôi muốn sử dụng $ nin? Cùng một loại hành vi bí ẩn xuất hiện, và sau đó chúng tôi bắt đầu nghi ngờ tất cả các kết quả truy vấn chúng tôi đã nhận được. Ngoài ra, cảm ơn cho cụm từ "mảng mảng". – dgorur

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