Reputation: 2816
Eg. The collection: { a: 1, b: 2, c: 3 } { a: 11, b: 12, c: 13 } { a: 111, b: 122 }
The query: db.records.find( {}, {b, c} )
What I am trying to get here is something like this: { b: 2, c: 3 } { b: 12, c: 13 } { b: 122, c: null }
But I am getting only: { b: 2, c: 3 } { b: 12, c: 13 }
Is it possible to get what I want in a single query to Mongo?
Upvotes: 0
Views: 73
Reputation: 151112
This can be done using aggregate and the $ifNull operator:
db.records.aggregate([{$project: { _id: 0, b: 1, c: {$ifNull: ["$c" , null ]} }}])
It is still worth explaining the general effects of null
, as there is a difference between whether a key exists in a document or if it contains null
. Consider the following query output:
> db.records.find({},{ _id: 0, b:1, c:1})
{ "b" : 2, "c" : 3 }
{ "b" : 12, "c" : 13 }
{ "b" : 122 }
> db.records.find({ c:{$exists: true}},{ _id: 0, b:1, c:1})
{ "b" : 2, "c" : 3 }
{ "b" : 12, "c" : 13 }
> db.records.find({ c:{$exists: false}},{ _id: 0, b:1, c:1})
{ "b" : 122 }
>
This shows the query with a projection for only the b and c fields, so that is what is returned in the first instance. The third document is returned because we didn't limit we just projected. Using $exists as a query modifier this can be filtered either way as the c field does not exist in one of the documents.
Let's suppose we alter the third document and then look at the queries again:
> db.records.update({ _id: ObjectId("52ed85ecb87e33d680adb0fa") }, {$set: { c: false }})
> db.records.find({},{ _id: 0, b:1, c:1})
{ "b" : 2, "c" : 3 }
{ "b" : 12, "c" : 13 }
{ "b" : 122, "c" : false }
> db.records.find({ c:{$exists: true}},{ _id: 0, b:1, c:1})
{ "b" : 2, "c" : 3 }
{ "b" : 12, "c" : 13 }
{ "b" : 122, "c" : false }
> db.records.find({ c: true },{ _id: 0, b:1, c:1})
>
> db.records.find({ c: false },{ _id: 0, b:1, c:1})
{ "b" : 122, "c" : false }
>
So after setting a false value for c we can see the field in the results. It responds to the exists operator because it is there, and if the query is changed to filter results it will return as appropriate.
More information on the link: http://docs.mongodb.org/manual/faq/developers/#faq-developers-query-for-nulls
Upvotes: 0
Reputation: 13443
Projections (second param in your find
command) should be in this format: { b: 1, c: 1 }
I get output similar to what you're looking for with this syntax:
> db.records.find( { }, { _id: 0, b: 1, c: 1 } )
{ "b" : 2, "c" : 3 }
{ "b" : 12, "c" : 13 }
{ "b" : 122 }
Upvotes: 2