0

In a $project stage, I want to create a dummy (boolean) field which will be:

  • true if some subfield exists
  • false otherwise

This is my data. The subfield of interest is address.country, which may be missing:

{ 
    "_id" : "1", 
    "name" : "John", 
    "address" : {
        "city" : "New York", 
        "country" : "USA"
    }
}
{ 
    "_id" : "2", 
    "name" : "Paul", 
    "address" : {
        "city" : "Paris"
    }
}

The user named Paul has no address.country subfield, so I want his dummy field to be false.

Here is what I tried:

db.getCollection("items").aggregate(
    [
        { 
            "$match" : {

            }
        },
        {
            "$project": {
                "name": true,
                "has_country": { "$address.country": { "$exists": true } }
            }
        }
    ]
);

This failed with InvalidPipelineOperator and message Unrecognized expression '$address.country'. I found the question here but this use case is slightly different and the answer was not very understandable.

Johann8
  • 649
  • 7
  • 20

1 Answers1

0

Comparing the subfield to null does the trick:

db.getCollection("items").aggregate(
    [
        { 
            "$match" : {

            }
        },
        {
            "$project": {
                "name": true,
                "has_country": { "$gt": [ "$address.country", null ] }
            }
        }
    ]
);

On the mentioned data, this returns the following:

{ 
    "_id" : "1", 
    "name" : "John", 
    "has_country" : true
}
{ 
    "_id" : "2", 
    "name" : "Paul", 
    "has_country" : false
}
Johann8
  • 649
  • 7
  • 20