1

What I'm trying to accomplish is to have an Array of Objects (the subdocument way: defined in a Schema) inside a main document, and I want this subdocument to behave as a document itself.

This is, when pushing an Object into the Subdocument Array, I would like that it threw an error:

  • if any of the unique fields of the object being inserted are already taken
  • if the object being inserted doesn't match the TemplateSchema

This would be my main document:

var ApplicationSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    unique: true
  },
  description: {
    type: String
  },
  ...
  templates: {
    type: [TemplateSchema]
  }
});

and the following would be the subdocument, the templates field inside the ApplicationSchema:

var TemplateSchema = mongoose.Schema({
  name: {
    type: String,
    required: true,
    unique: true,
    sparse: true
  },
  description: {
    type: String
  },
  ...
});

In this case, when I am trying to:

  1. add a new object with an already existing name, or
  2. push any trash into my subdocument

it's happening that:

  1. no error is being thrown about the duplicated field value
  2. the trash object (i.e. {some: "trash"}) is being inserted - not really the object itself, but it's pushing an empty template object inside the templates array

and I can't figure out why.

Here is the query I'm using to insert new template objects into the templates array inside the main document, which I guess is here where it is not working as expected:

exports.create = function(id, objTemplate, callback) {
  ApplicationModel.findByIdAndUpdate(
      { _id: id },
      {
        $push: {
          "templates": objTemplate
        }
      },
      {
        safe: true,
        upsert: true,
        new : true
      },
      function(err, application) {
        // handle stuff
      }
    );
};
charliebrownie
  • 5,777
  • 10
  • 35
  • 55
  • Can you share some sample data – Alok Deshwal Oct 26 '15 at 22:09
  • @AlokDeshwal do you mean an example of an object I would add to `templates`? – charliebrownie Oct 26 '15 at 22:20
  • 2
    You don't want "unique" there as it creates an index that is "unique" across the collection and not just the array of that document. Instead you will want to that that the "name" property in the array does not contain the item you are adding. i.e `{ "_id": id, "templates.name": { "$ne": objTemplate.name } }`. You also cannot mix this with "upsert" since you would end up creating a new document where the array element was not present. There are already answers here that deal with this. – Blakes Seven Oct 26 '15 at 22:21
  • 2
    Example of unique handling and upserts here: http://stackoverflow.com/a/32447789/5031275 – Blakes Seven Oct 26 '15 at 22:30
  • Thank you very much @BlakesSeven. As I am new to `mongo`, some aspects seem a bit hard to assimilate at the beginning and make things work as expected. – charliebrownie Oct 26 '15 at 22:36
  • @BlakesSeven and why if I pass a trash object i.e. `{ some: "trash" }`, it's inserting it into the `templates` array? Shouldn't it be complaining for not folllowing the `TemplateSchema`? – charliebrownie Oct 27 '15 at 00:29
  • Nope. The idea here is not "exceptions" as would be thrown by a duplicate key ( and as noted this does not apply here ) but rather to determine where nothing was updated due to the value already being present. Then you can basically report that you cannot update since that value exists when the modified count is `0`. – Blakes Seven Oct 27 '15 at 00:43

0 Answers0