I have a set of "elements" of 5 elements, each of which has an identifier and an array
{ _id: ObjectId("51c21bec162c138d9d0001a7"), tags: [ { name: "a", type: "tag" }, { name: "b", type: "tag" }, { name: "c", type: "note" } ] } { _id: ObjectId("51c21ca22c69904840000178"), tags: [ { name: "a", type: "tag" }, { name: "d", type: "tag" }, { name: "c", type: "note" } ] } { _id: ObjectId("51c21cc1478cf6691a0001b4"), tags: [ { name: "d", type: "tag" }, { name: "b", type: "tag" }, { name: "c", type: "note" } ] } { _id: ObjectId("51c22292162c13b1ff000222"), tags: [ { name: "a", type: "tag" }, { name: "d", type: "tag" }, { name: "e", type: "note" } ] } { _id: ObjectId("51c222e926d602a57d0001d8"), tags: [ { name: "a", type: "tag" }, { name: "d", type: "note" }, { name: "c", type: "note" } ] }
The goal is to return all elements with tags "a" and "d", where the tags have a type tag. You might have thought that would do this:
find({"tags.name":{"$all":["a","d"]}, "tags.type":'tag'})
returns 3 documents, which is incorrect, but I found out that this query is executing or. So I'm trying to use "$ elemMatch" to do this, in what I thought was the most intuitive way, but
find({"tags":{"$elemMatch":{'name':{'$all':["a","d"]}, "type":'tag'}}})
does not return documents.
The same query if I need only those elements with tags 'a':
find({"tags":{"$elemMatch":{'name':{'$all':["a"]}, "type":'tag'}}})
presumably because $ all gets mapped to something like $ eq.
In the end, I found that for my initial GOAL , the following should be done:
find({"tags":{"$all":[{'$elemMatch':{'name':"a", "type":'tag'}}, {'$elemMatch':{'name':"d", "type":'tag'}} ]}})
returns two valid documents.
But this syntax is terrible! I need to expand the array ["a", "d"] myself in the request. What if I write a general query mechanism and want to say that several fields of an embedded document are arrays, and I want a specific subset of the values ββfrom each array?
Is there a better way to do this? Best syntax?