0

I have following model and schemas in mongoose :

const Doc = mongoose.model(
  "Doc",
  new mongoose.Schema({
    name: String,
    subDocs: [SubDoc],
  })
);

const SubDoc = new mongoose.Schema({
  name: String,
  subSubDocs: [SubSubDoc],
});

const SubSubDoc = new mongoose.Schema({
  name: String,
});

This code adds a uniquely named embedded SubDoc to the parent Doc. By "uniquely named" I mean it will not create a subdocument if another subdocument in the parent has the same value for "name":


const createUniqueSubDoc = (docId, name) => {
  return db.Doc.findOneAndUpdate(
    { _id: docId, "subDocs.name": { $ne: name } },
    {
      $push: {
        subDocs: {
          name: name,
        },
      },
    },
    { new: true, useFindAndModify: false }
  );
};

const run = async (doc) => {
  let doc = await db.Doc.create({name:"Main document"})  
  createUniqueSubDoc(doc._id, "sub document name");
};

run();

addToSet doesn't work with dates or id's so I'm $ne as suggested here.

But how do I add a uniquely named embedded SubSubDoc to the already embedded SubDoc's subSubDoc field? You can't query the embedded SubDoc with findOneAndUpdate because it's only a schema not a model like the Doc model.

Dashiell Rose Bark-Huss
  • 2,173
  • 3
  • 28
  • 48

1 Answers1

0

using MongooseArray methods:


const createUniqueSubSubDoc = async function (docId, subDocId, subSubDoc) {
  const doc = await db.Doc.findById(docId);
  const subDoc = doc.subDocs.id(subDocId);
  if (subDoc.subSubDocs.find((ssd) => ssd.name == subSubDoc.name))
    return "oops! you already gave another SubSubDoc this name";
  subDoc.subSubDocs.push(subSubDoc);
  await doc.save();
  return doc.subDocs.id(subDocId);
};


createSubSubDoc(
  "5f56d9621222bbcc3bf4ee41", // the id for a Doc
  "5f56d9631222bbcc3bf4ee42", // the id for a SubDoc of that Doc
  { name: "subSubDoc name" } // the object for the new SubSubDoc
);

git repo

Dashiell Rose Bark-Huss
  • 2,173
  • 3
  • 28
  • 48