2

I see a lot of similarly worded questions here, but none has solved my problem.

I have a document like this:

{'_id': ObjectId('5006916af9cf0e7126000000'),'data': [{'count': 0,'alis':'statsministeren','avis':'Ekstrabladet'}, {'count': 0,'alis':'thorning','avis':'Ekstrabladet'}, {'count': 0,'alis':'socialdemokratiets formand','avis':'Ekstrabladet'}, {'count': 0,'alis':'lars barfod','avis':'Ekstrabladet'}, {'count': 0,'alis':'formand for det konservative folkeparti','avis':'Ekstrabladet'}, {'count': 0,'alis':'s\xf8vndal','avis':'Ekstrabladet'}, {'count': 0,'alis': u"sf's formand",'avis':'Ekstrabladet'}, {'count': 0,'alis':'m\xf6ger','avis':'Ekstrabladet'}, {'count': 0,'alis':'lars l\xf8kke','avis':'Ekstrabladet'}, {'count': 0,'alis':'l\xf8kke rasmussen','avis':'Ekstrabladet'}, {'count': 0,'alis':'lederen af danmarks st\xf8rste parti','avis':'Ekstrabladet'}, {'count': 0,'alis':'Pia Kj\xe6rsgaard','avis':'Ekstrabladet'}, {'count': 0,'alis':'statsministeren','avis':'Information'}, {'count': 1,'alis':'thorning','avis':'Information'}, {'count': 0,'alis':'socialdemokratiets formand','avis':'Information'}, {'count': 0,'alis':'lars barfod','avis':'Information'}, {'count': 0,'alis':'formand for det konservative folkeparti','avis':'Information'}, {'count': 0,'alis':'s\xf8vndal','avis':'Information'}, {'count': 0,'alis': u"sf's formand",'avis':'Information'}, {'count': 0,'alis':'m\xf6ger','avis':'Information'}, {'count': 0,'alis':'lars l\xf8kke','avis':'Information'}, {'count': 0,'alis':'l\xf8kke rasmussen','avis':'Information'}, {'count': 0,'alis':'lederen af danmarks st\xf8rste parti','avis':'Information'}, {'count': 0,'alis':'Pia Kj\xe6rsgaard','avis':'Information'}, {'count': 0,'alis':'statsministeren','avis':'Berlingske'}, {'count': 0,'alis':'thorning','avis':'Berlingske'}, {'count': 0,'alis':'socialdemokratiets formand','avis':'Berlingske'}, {'count': 0,'alis':'lars barfod','avis':'Berlingske'}, {'count': 0,'alis':'formand for det konservative folkeparti','avis':'Berlingske'}, {'count': 1,'alis':'s\xf8vndal','avis':'Berlingske'}, {'count': 0,'alis': u"sf's formand",'avis':'Berlingske'}, {'count': 0,'alis':'m\xf6ger','avis':'Berlingske'}, {'count': 0,'alis':'lars l\xf8kke','avis':'Berlingske'}, {'count': 0,'alis':'l\xf8kke rasmussen','avis':'Berlingske'}, {'count': 0,'alis':'lederen af danmarks st\xf8rste parti','avis':'Berlingske'}, {'count': 0,'alis':'Pia Kj\xe6rsgaard','avis':'Berlingske'}, {'count': 0,'alis':'statsministeren','avis':'JP'}, {'count': 0,'alis':'thorning','avis':'JP'}, {'count': 0,'alis':'socialdemokratiets formand','avis':'JP'}, {'count': 0,'alis':'lars barfod','avis':'JP'}, {'count': 0,'alis':'formand for det konservative folkeparti','avis':'JP'}, {'count': 0,'alis':'s\xf8vndal','avis':'JP'}, {'count': 0,'alis': u"sf's formand",'avis':'JP'}, {'count': 1,'alis':'m\xf6ger','avis':'JP'}, {'count': 0,'alis':'lars l\xf8kke','avis':'JP'}, {'count': 0,'alis':'l\xf8kke rasmussen','avis':'JP'}, {'count': 0,'alis':'lederen af danmarks st\xf8rste parti','avis':'JP'}, {'count': 0,'alis':'Pia Kj\xe6rsgaard','avis':'JP'}, {'count': 0,'alis':'statsministeren','avis':'BT'}, {'count': 0,'alis':'thorning','avis':'BT'}, {'count': 0,'alis':'socialdemokratiets formand','avis':'BT'}, {'count': 0,'alis':'lars barfod','avis':'BT'}, {'count': 0,'alis':'formand for det konservative folkeparti','avis':'BT'}, {'count': 0,'alis':'s\xf8vndal','avis':'BT'}, {'count': 0,'alis': u"sf's formand",'avis':'BT'}, {'count': 0,'alis':'m\xf6ger','avis':'BT'}, {'count': 0,'alis':'lars l\xf8kke','avis':'BT'}, {'count': 0,'alis':'l\xf8kke rasmussen','avis':'BT'}, {'count': 0,'alis':'lederen af danmarks st\xf8rste parti','avis':'BT'}, {'count': 0,'alis':'Pia Kj\xe6rsgaard','avis':'BT'}, {'count': 0,'alis':'statsministeren','avis':'Politiken'}, {'count': 0,'alis':'thorning','avis':'Politiken'}, {'count': 0,'alis':'socialdemokratiets formand','avis':'Politiken'}, {'count': 0,'alis':'lars barfod','avis':'Politiken'}, {'count': 0,'alis':'formand for det konservative folkeparti','avis':'Politiken'}, {'count': 0,'alis':'s\xf8vndal','avis':'Politiken'}, {'count': 0,'alis': u"sf's formand",'avis':'Politiken'}, {'count': 0,'alis':'m\xf6ger','avis':'Politiken'}, {'count': 0,'alis':'lars l\xf8kke','avis':'Politiken'}, {'count': 0,'alis':'l\xf8kke rasmussen','avis':'Politiken'}, {'count': 0,'alis':'lederen af danmarks st\xf8rste parti','avis':'Politiken'}, {'count': 0,'alis':'Pia Kj\xe6rsgaard','avis':'Politiken'}],'time':'2012-07-18 12:35:22.241245'}

I.e.:

{_objectId : xxx, time: yyy, data :[ 72 similar dicts in this array ]}

I want to retrieve values from within one of the 72 dicts.

My first attempt was something along these lines:

db.observations.find({'data.avis':'Ekstrabladet', 'data.alis':'thorning'}, {'data.count':1})

That would retrieve 72 count dicts, when what I really wanted was the count value for the array which satisfies both avis:ekstrabladetand alis:thorning (only one array). But instead mongo returns the whole document.

I have foundt $elemMatch, but I get the same output.

db.observations.find({'data' : {$elemMatch: {'alis':'thorning','avis':'Ekstrabladet'}}},{'data.count':1})

I guess I could iterate over the complete document in python (this is for a flask app), but it doesn't seem very elegant.

So my question is: How do I reach inside a document and grab values from a nested document of arrarys?

Bonus: As I am new to all sorts of databases I only chose mongodb because it seemed very nice and flexible, and because I don't work with critcal data. But I have no need for scalability and could use e.g. sqlite instead. If you have strong opinions about me using the wrong tool for the job - then please abuse me.

Andreas
  • 6,066
  • 12
  • 49
  • 65
  • if you frequently manipulate single sub document did you consider a different schema, maybe where each document is like your elements of the array plus the top level fields? – Asya Kamsky Jul 18 '12 at 12:47
  • @AsyaKamsky well - yes/no. Yes I have thought about, no I am just muddeling along here. However: The structure represents information that is fetched at the same time, for that reason it makes more semantically sense for me like this. But I should probably look into a new schema. – Andreas Jul 18 '12 at 13:21

1 Answers1

2

You cannot return just the selected subdocument. You'll get all of them. So you'll have to filter on the client side.

$elemMatch is of the essence, though, otherwise you would not be matching avis and alis against the same array entry (having one each that matches either would suffice, AND vs OR in a way).

Community
  • 1
  • 1
Thilo
  • 241,635
  • 91
  • 474
  • 626
  • Damn... I will have to take your word (backed up by almost 60K karma) for it ;-) ps. When I run from my python app the exact same find query which works in the shell, the output is a `pymongo.cursor.Cursor object`- which I have no idea what to do with (so I don't know hot to filter on client side). - I'll most likelly figure it out. But puts it here also ;-) – Andreas Jul 18 '12 at 14:16
  • just for any other newbies: the `Cursor`object is the whole query returned. If there is more than one document in the query, you have to loop though the object. something like {% for i in results %} print {{i}} {% endfor % } – Andreas Jul 19 '12 at 11:21