Mongoose: Mix included and excluded selection fields

Created on 22 Jun 2013  路  6Comments  路  Source: Automattic/mongoose

I use white-lists to pull only certain fields from mongo, like this:

{
field: 1
subdocument: 1
}

Additionally, I wanted to exclude a subfield like this:

{
field: 1
subdocument: 1
'subdocument.subfield': 0
}

I saw a message that this isn't currently supported. Are there any plans to support this? Or is there a workaround that might give the same result?

won't fix

Most helpful comment

@MidnightP :

1) MongoDB includes _id by default, you need to specifically _exclude_ it. This is the only field that's included by default unless you use select in your schema. See https://docs.mongodb.com/manual/tutorial/project-fields-from-query-results/#suppress-id-field
2) Projections only apply to properties stored in MongoDB, and virtuals are not stored in MongoDB. If you have a virtual that shouldn't be defined if a field isn't selected, you can check in the virtual getter for this.isSelected('otherField')

All 6 comments

I would also appreciate this functionality. Did you ever discover a workaround?

No, I ended up getting the entire subdocument and deleting the parts I didn't want to pass on.

@ARAtlas docs for v3 say this is supported now:
http://mongoosejs.com/docs/api.html#query_Query-select

But I get an error:
{ [MongoError: Can't canonicalize query: BadValue Projection cannot have a mix of inclusion and exclusion.] name: 'MongoError' }

Not sure why?

Unfortunately those docs are incorrect, I need to fix those. The MongoDB server can't handle this particular case, its not really a mongoose limitation. The reasoning is that it's difficult to know exactly what you mean when you specify {a:1, b: 1, c: 0} - do you mean "include everything except for c" or "exclude everything except for a and b"? You're right in that this is more clear when you have a nested doc, but the mongodb server just doesn't support this.

For a workaround on the original question, you would have to either explicitly list out the fields in subdocument that you want or explicitly exclude all top-level fields you want to hide.

It looks like this is still in the docs... See under heading "Query conditions and other options".

I was trying to do this because I somehow always receive _id in addition to others fields when using select within a population. Besides _id, I also seem to receive virtuals without asking for them. Is there a reason for this? Is there a way around it? Would be great to learn more about it!

@MidnightP :

1) MongoDB includes _id by default, you need to specifically _exclude_ it. This is the only field that's included by default unless you use select in your schema. See https://docs.mongodb.com/manual/tutorial/project-fields-from-query-results/#suppress-id-field
2) Projections only apply to properties stored in MongoDB, and virtuals are not stored in MongoDB. If you have a virtual that shouldn't be defined if a field isn't selected, you can check in the virtual getter for this.isSelected('otherField')

Was this page helpful?
0 / 5 - 0 ratings