How to project whether field exists
Asked Answered
A

1

8

If I have documents with similar structure as below. I am updating them with the results of the computations and I want to know whether the result has already been inserted into a document or not. Let's say for each document I run computation 'c' and computation 'd'. Now I want to display a table of all documents and show whether a computation 'd' has been already carried out. And for this table I do not care about computation 'c'.

{
"_id":1
"a":1,
"resultsOfComputation":{
   "c":{large embedded document},
   "d":{large embedded document}   
   }
}

{
"_id":2
"a":1,
"resultsOfComputation":{
   "c":{large embedded document}
   }
}

I would like to get a result that tells me whether a document contains a specific field. For example, I would like to know whether it contains field "resultsOfComputation.d", no matter what is the value of that field.

An example of the result of the query for "resultsOfComputation.d" would be:

{
"_id":1
"a":1,
"resultsOfComputation":{
   "d":true   
   }
}

{
"_id":2
"resultsOfComputation":{
   "d":false
   }
}

If "resultsOfComputation.d" is not in the document it can also be undefined, which is also ok:

{
"_id":1
"a":1,
"resultsOfComputation":{
   "d":true   
   }
}

{
"_id":2
"a":1,
"resultsOfComputation":{}
}

In general, the idea is to get all the root elements of the documents, but only true/false/undefined for the selected (one) result of computation, since the result of computation is a large embedded document.

Archidiaconal answered 2/8, 2016 at 12:25 Comment(0)
C
14

Run the following aggregation pipeline to get the desired results:

db.collection.aggregate([
    {
        "$project": {
            "a": 1,
            "resultsOfComputation": {
                "d": { "$gt": ["$resultsOfComputation.d", null] }   
            }
        }
    }
])

Sample Output

/* 1 */
{
    "_id" : 1,
    "a" : 1,
    "resultsOfComputation" : {
        "d" : true
    }
}

/* 2 */
{
    "_id" : 2,
    "a" : 1,
    "resultsOfComputation" : {
        "d" : false
    }
}
Councilman answered 2/8, 2016 at 12:49 Comment(3)
I am blown away by this query! wow! just wow! But can you help me understand, how a $gt is giving an output of true or false?Weathersby
This linked answer explains it all.Councilman
this answer works, unfortunately using aggregate was quite slow for me, especially when I added skip to the pipeline. In the end, I just used find instead of aggregate, with a projection that includes all root elements of document and one field that I know that always is inside "resultsOfComputation.d" and then I check whether this field is undefined or not.Archidiaconal

© 2022 - 2024 — McMap. All rights reserved.