mongodb

MongoDB projection does not work for nested properties when the property name has a digit


I have weather documents like this:

{
 "_id": "some_id",
 "temp_f": 65.8,
 "current_observation": {
   "rain_day_in": 0,
   "soil_moisture_1": 0
   "soil_moisture_1_day_high": 0
 }
 "date": "12/23/2021",
 "date_and_time": "2021-12-23T20:34:21",
 ... many more properties here
}

Running the following find command (find the most recent document and flatten the properties):

db.getCollection('weather').find({}, {
    "temp_f": 1,
    "rain_day_in": "$current_observation.rain_day_in",
    "soil_moisture_1": "$current_observation.soil_moisture_1",
    "soil_moisture_1_day_high": "$current_observation.soil_moisture_1_day_high",
    "date": 1,
    "_id": 0
}).sort({
    date_and_time: -1
}).limit(1);

I get the following result:

[
  {
    "temp_f": 66.6,
    "date": "03/12/2025",
    "rain_day_in": 0
  }
]

It returns all included properties except soil_moisture_1 and soil_moisture_1_day_high. Both have a digit in the name. Several other properties have a digit as part of the property name, and none of them are returned in the result if I include them. Is that digit causing the issue? How can I fix the command to get those properties in the result?

Using MongoBD v7.0.15


Solution

  • Cannot reproduce the issue you're facing with your example data. Projection works as expected, here: https://mongoplayground.net/p/JNhbhhKFvAP.

    It's possible that the first document (or some documents) don't have those fields, so they are being skipped in the output. With sort and limit 1, you only see the first document. Add a filter for { "_id": "some_id" } and see if documents which have those fields have the correct output.

    If you always want those fields in the output, then use $ifNull in the projection and provide a good default, like 0 or null or -1000:

    db.getCollection('weather').find({},
    {
      "temp_f": 1,
      "rain_day_in": {
        $ifNull: ["$current_observation.rain_day_in", -1000]
      },
      "soil_moisture_1": {
        $ifNull: ["$current_observation.soil_moisture_1", -1000]
      },
      "soil_moisture_1_day_high": {
        $ifNull: ["$current_observation.soil_moisture_1_day_high", -1000]
      },
      "date": 1,
      "_id": 0
    }).sort({
      date_and_time: -1
    }).limit(1);
    

    Mongo Playground with more documents