4

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.

2 Answers 2

12

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.

Sign up to request clarification or add additional context in comments.

7 Comments

Wow, that seems to work! what made you think of adding another "dummy" field?
I've done a lot with mongo and there always seems to be a workaround to making their code work as expected =p
Thanks, that's awesome (if unexpected) solution.
I can't believe there isn't a more official solution to this...? I asked myself the same question as OP the moment I read about $slice. Which was around two seconds after reading about limiting fields, since those two articles are right next to each other...
Holyshit, I'm facing the same problem, isn't this a bug of pymongo? I can't believe this bug still exists today.
|
0

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

4 Comments

find_one({'_id' : 'lemons'}, { 'countries' : {'$slice' : [0,3] }, '_id' : 0 }) gives the same result as mentioned, I'll test how it works in mongo shell.
Mongo shell gives me the same result as well, unfortunately. I'm running 2.2.3 version of MongoDB, if that matters.
Looks like this is by design and is an known issue: jira.mongodb.org/browse/SERVER-3378. You'd have to explitly suppress all other fields, but as you've explained you won't necessarily know them all if your adding to a dynamic schema
Ok, I guess than I better change _id: 0 to _id: 1, this way MongoDB returns only sliced array plus id field, which at least is predictable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.