pythonmongodbpymongomongokit

field selection within mongodb query using dot notation


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.


Solution

  • 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).