0

I need to query documents with mongoDb that contain nested arrays. I see a lot of examples using the simple $in operator. The only problem is that I strictly need to check for proper subsets.

Consider the following document.

{data: [[1,2,3], [4,5,6]]}

The query needs to be able to get documents with all of [1,2,3] where 1,2,3 can be in any order, which rules out the following query, because it will only match in the correct order.

{data:{$elemMatch:{$all:[[1,2,3]]}}}

I've also tried nested $elemMatch operators with no success, because the $in operator will return the document even if only one element matches such as the following.

 {data:{$elemMatch:{$elemMatch:{$in:[1,4]}}}}
Community
  • 1
  • 1
Gary Drocella
  • 337
  • 1
  • 2
  • 11

2 Answers2

0

Not sure what your actual query looks like, but this should do what you need: db.documentDto.find({"some_field":{"$elemMatch":{"$in":[1,2,3]}} })

snolan
  • 1
  • Please go back and carefully re-read my question. Especially, where I explicitly state "The only problem is that I strictly need to check for proper subsets. ". – Gary Drocella Apr 21 '15 at 23:28
  • Ok for "subset" portion of your question, have you looked at "setIsSubset"? http://docs.mongodb.org/manual/reference/operator/aggregation/setIsSubset/ – snolan Apr 22 '15 at 02:53
0

I haven't got a complete answer (and not much time as its late here) but I would consider

  1. Using aggregation pipeline instead of a query if your not already
  2. Use $unwind operator to deconstruct your nested arrays
  3. Use $sort to sort the contents of the arrays - so you can now compare
  4. Use $match to filter out the arrays which don't fit the array subset values as you can now check based on order.
  5. Use $group to group the result back together based on the _id value

Ref: http://docs.mongodb.org/manual/reference/operator/aggregation-pipeline/ will give you info on each of the above.

From a quick search I came up with a similar question/example that might be helpful: Mongodb sort inner array

Community
  • 1
  • 1
nomDePlum
  • 101
  • 5
  • I'd rather not, being the find function that is being used converts the query into an aggregation. The unit test is only testing the insertion of the document so I might just go ahead and use an aggregation instead. I'll think about it, and wait to see if there is a possible solution using queries. – Gary Drocella Apr 21 '15 at 23:26
  • I couldn't see a way to do it with a find() which is why I suggested aggregation. I believe using the outline above you should be able to achieve what you are looking to do. – nomDePlum Apr 22 '15 at 23:17