In MongoDB how to return only part of array?

2019-01-28 06:31发布

问题:

Consider collection "fruits", in which I have this document (I'm using Python's pymongo driver, btw):

{
    '_id'       : 'lemons',
    'weight'    : 58,
    'shape'     : 'oval',
    'countries' : ['Mexico', 'Turkey', 'Argentina', 'SAfrica', 'US']
}

Now, if I want to get only the 'countries' field, this query works just fine:

In [1]: find_one('lemons', { 'countries' : 1, '_id' : 0 })
Out[1]: {u'countries': [u'Mexico', u'Turkey', u'Argentina', u'SAfrica', u'US']}

But it turns out that what I really need is just list of few top-countries, not all of them, so I'm using "$slice" instead of plain True/1:

In [239]: c.find_one('lemons', { 'countries' : { '$slice' : [0, 3] }, '_id' : 0 })
Out[239]: 
{u'countries': [u'Mexico', u'Turkey', u'Argentina'],
 u'shape': u'oval',
 u'weight': 58}

Well, number of countries has shrinked, but now it gives me whole lot of other unrelated information!

Q: Is there any way to show only those fields that I have asked for? Additionally listing '_id' as exception is fine, because this field is always presented, but I can't be sure about other fields, since MongoDB is scheme-less and I intend to use this feature to add additional fields if needed.

回答1:

Have you tried adding another inclusion projection? I think you may be able to add something trivial like foo:1 (that is not a real field) and it should work.

Like so:

{ 'countries' : { '$slice' : [0, 3] }, '_id' : 0, foo : 1 }

If it doesn't work I suggest filing a bug with mongo. They are actually very good about responding to bugs.



回答2:

That's strange because that's not the behavior when running in the mongo console.

Have you tried putting 'lemons' in curly braces so it's valid JSON syntax?

find_one({'_id':'lemons'}, { 'countries' : 1, '_id' : 0 })

It looks to me like it's applying your $slice projection to all of the fields, so it could be some weird syntax issue with the pymongo driver