0

I searched many questions here and other articles on the web, but they all seem to describe somehow different cases from what I have at hand.

I have User schema:

{
    username: { type: String },
    lessons: [
        {
            lesson: { type: String },
            result: { type: String }
        }
    ]
}

I want to add new element into lessons or skip, if there is already one with same values, therefore I use addToSet:

const dbUser = await User.findOne({ username })
dbUser.lessons.addToSet({ lesson, result: JSON.stringify(result) })
await dbUser.save()

However it makes what seems to be duplicates:

// first run
[
  {
    _id: 60c80418f2bcfe5fb8f501c1,
    lesson: '60c79d81cf1f57221c05fdac',
    result: '{"correct":2,"total":2}'
  }
]

// second run
[
  {
    _id: 60c80418f2bcfe5fb8f501c1,
    lesson: '60c79d81cf1f57221c05fdac',
    result: '{"correct":2,"total":2}'
  },
  {
    _id: 60c80470f2bcfe5fb8f501c2,
    lesson: '60c79d81cf1f57221c05fdac',
    result: '{"correct":2,"total":2}'
  }
]

At this point I see that it adds _id and thus treats them as different entries (while they are identical).

What is my mistake and what should I do in order to fix it? I can change lessons structure or change query - whatever is easier to implement.

3
  • You can check for the lesson and result values (along with username you are already filtering on) in the query before the update (save). Commented Jun 15, 2021 at 2:24
  • @prasad_ so what you suggest is simply if (await User.findOne({ username }, { lesson })) condition (let's ignore result)? Commented Jun 15, 2021 at 2:39
  • 1
    Something like this: mongoose “Find” with multiple conditions. The lesson condition can be coded as "lessons.lesson": "math", for example. Commented Jun 15, 2021 at 3:06

1 Answer 1

1

You can create sub-documents avoid _id. Just add _id: false to your subdocument declaration.

const userSchema = new Schema({
  username: { type: String },
  lessons: [
    {
      _id: false,
      lesson: { type: String },
      result: { type: String }
    }
  ]
});

This will prevent the creation of an _id field in your subdoc, and you can add a new element to the lesson or skip it with the addToSet operator as you did.

Sign up to request clarification or add additional context in comments.

1 Comment

It works now. Without _id it finally compares them right.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.