2013-04-19 37 views
8

Giả sử tôi có chèn một bộ tài liệu mỗi trường có trường array. Tôi muốn tìm tất cả các tài liệu sao cho trường array của họ là một tập hợp con của một mảng truy vấn. Ví dụ, nếu tôi có các tài liệu sau,Tìm tài liệu trong MongoDB có trường mảng là một tập hợp con của một mảng truy vấn

collection.insert([ 
    { 
    'name': 'one', 
    'array': ['a', 'b', 'c'] 
    }, 
    { 
    'name': 'two', 
    'array': ['b', 'c', 'd'] 
    }, 
    { 
    'name': 'three', 
    'array': ['b', 'c'] 
    } 
]) 

và tôi truy vấn collection.find({'array': {'$superset': ['a', 'b', 'c']}), tôi sẽ mong đợi để xem tài liệu onethree như ['a', 'b', 'c']['b', 'c'] đều tập con của ['a', 'b', 'c']. Nói cách khác, tôi muốn làm ngược lại truy vấn $all của Mongo, chọn tất cả các tài liệu sao cho mảng truy vấn là một tập hợp con của trường array của tài liệu. Điều này có thể không? và nếu có, làm thế nào?

+0

Bạn cần thực hiện một số IMHO tổng hợp. –

Trả lời

9

Có một cách đơn giản để thực hiện việc này với khung tổng hợp hoặc với truy vấn tìm kiếm.

Find truy vấn là đơn giản, nhưng bạn cần phải sử dụng $ elemMatch điều hành:

> db.collection.find({array:{$not:{$elemMatch:{$nin:['a','b','c']}}}}, {_id:0,name:1}) 

Lưu ý rằng điều này chỉ ra rằng chúng ta muốn không phù hợp với một mảng trong đó có một yếu tố đó là (đồng thời) không bằng 'a', 'b' hoặc 'c'. Tôi đã thêm một phép chiếu chỉ trả về trường tên của tài liệu kết quả là tùy chọn.

8

Trong MongoDB, cho lĩnh vực mảng:

"$in:[...]" means "intersection" or "any element in", 
"$all:[...]" means "subset" or "contain", 
"$elemMatch:{...}" means "any element match" 
"$not:{$elemMatch:{$nin:[...]}}" means "superset" or "in" 
2

Để làm điều này trong bối cảnh của sự kết hợp, bạn có thể sử dụng $setIsSubset:

db.collection.aggregate([ 
    // Project the original doc and a new field that indicates if array 
    // is a subset of ['a', 'b', 'c'] 
    {$project: { 
     doc: '$$ROOT', 
     isSubset: {$setIsSubset: ['$array', ['a', 'b', 'c']]} 
    }}, 
    // Filter on isSubset 
    {$match: {isSubset: true}}, 
    // Project just the original docs 
    {$project: {_id: 0, doc: 1}} 
]) 

Lưu ý rằng $setIsSubset đã được bổ sung trong MongoDB 2.6.

+1

đẹp nhất. Tôi đã loại bỏ tập hợp không hiệu quả cũ khỏi câu trả lời của mình vì câu trả lời này thanh lịch hơn và bây giờ đã có sẵn trong một thời gian. –

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