Search code examples
mongodbmongoosemongoose-schema

Select a same field from a list of similar nested fields in mongoose


I have a schema.

const placeSchema = new Schema({
    description: {
      fr: String,
      en: String,
    },
    comment: {
      fr: String,
      en: String,
    },
    ...
    ...
});

const Place= mongoose.model('Place', placeSchema);

module.exports = Place;

If I want to get only 'en' value I am currently using

await Place.find({}, '-description.fr -comment.fr ...')

If the number of similar fields increases so does the length of the query. Is there a way to select all the similar fields like maybe $field.fr?


Solution

  • Technically yes there is a way. using $objectToArray and doing some structure manipulation.

    It would look something like this:

    db.collection.aggregate([
      {
        $match: {} //match your document.
      },
      {
        $addFields: {
          rootArr: {
            $objectToArray: "$$ROOT"
          }
        }
      },
      {
        $unwind: "$rootArr"
      },
      {
        $match: {
          "rootArr.v.en": {
            $exists: true
          }
        }
      },
      {
        $group: {
          _id: "$_id",
          data: {
            $push: {
              k: "$rootArr.k",
              v: "$rootArr.v.en"
            }
          }
        }
      },
      {
        $replaceRoot: {
          newRoot: {
            $arrayToObject: "$data"
          }
        }
      }
    ])
    

    Mongo Playground

    It's a little "hacky" thought, how strict are your schema needs? Have you considered building it under the following structure?:

    const placeSchema = new Schema({
        data: [
            {
                lang: String,
                description: String,
                comment: String,
                ...
            }
        ]
    });