How can I return data from this embedded document (using the positional operator?)


#1

I… admittedly asked a grossly similar question to this quite recently, but am still confused on something not-quite-exactly-the-same, this time involving the positional operator, probably. Terribly grateful for any help I can get, as always.

I have a collection called “Groups” that looks approximately like this:

      "_id" : "1111111",
      "InvitedUsers" : [{
               "_id" : "aaa111",
                "permissions" : "promote",
      "_id" : "222222",
      "InvitedUsers" : 
               "_id" : "bbb222",
               "permissions" : "none",

If I wanted to change the permissions field of just one of these subdocuments – the second one – I could update this using the below – this much works for me:

 Groups.update ({ '_id': "222222", 'InvitedUsers._id': "bbb222"},  { $set:{  'InvitedUsers.$.permissions': "whatever"}});

What I can’t figure out is how I can retrieve the data in the permission field of that second document only – specifically I need to return it in a meteor method. I tried an analogous construction involving ‘fields’ but had no luck. Is the positional operator the wrong way to approach this?


#2

well, it always return the whole subdocument - I mean object in array (not whole array)

meteor:PRIMARY> db.test.find({"prop.value": "hoax"},{"prop.$.value": 1}).pretty()
{
	"_id" : ObjectId("562548376beda013863e1910"),
	"prop" : [
		{
			"value" : "hoax"
		}
	]
}
{
	"_id" : ObjectId("5625491a6beda013863e1911"),
	"prop" : [
		{
			"value" : "hoax",
			"testvalue" : "dumb"
		}
	]
}
meteor:PRIMARY> 

so if you want just that 1 property and you are matching only 1 document, you can do something like findOne(stuff).InvitedUsers[0].permissions

if you want more results, I suggest http://docs.meteor.com/#/full/map


#3

Okay, this makes sense, but unfortunately in my actual case, I need to be able to find a single field in a subdocument of a specific document; I can’t have cases from other documents that match on the other field. So I tried this:

Groups.findOne ({’_id’: “222222”, ‘InvitedUsers._id’: “bbb222”}, {“InvitedUsers.$.permissions”: 1}).pretty()

…which I seems to match your example except for the fact that I’m specifying the _id of the parent document, but gave me errors. With pretty() at the end, I got
"Exception while invoking method ‘MethodName’ TypeError: Object [object Object] has no method ‘pretty’".

Sorry I wasn’t more clear initially, but how can I return just one field of one embedded document in one, specified parent document?


Only showing results of 1 sub-document / array item in view
#4

I was testing it directly in mongo, for you in Meteor this is the way (at least I would expect it)

Groups.findOne({'id': "222222", 'InvitedUsers.id': "bbb222"}, 
  fields: {"InvitedUsers.$.permissions": 1}
).InvitedUsers[0].permissions

#5

Ah, thank you! This did it! Hooray!

I’m still new to Meteor, and I must say, figuring out precisely the syntax needed to return data from documents (especially with subdocuments in the mix) has been the part been slowest to get a handle on, but one more case I grok now – thank you so much for the help. :cookie: