Learning about One-To-Many

I have a Schema.User and a Schema.Pattern which is a one-to-many relationship. I decided to split instead of embed because of the way the data is going to be queried. Also, patterns are going to have handful of projects as a one-to-many as well.

// ./models/user.model.ts

const userSchema = new mongoose.Schema({
  email: {
    type: String,
    unique: true
  },
  ...
})

const UserModel mongoose.model('User', userSchema)
export { UserModel }
// ./models/pattern.model.ts
const patternSchema = new mongoose.Schema({
  user: { type: Schema.Types.ObjectId},
  ...
})

const PatternModel mongoose.model('Pattern', patternSchema)
export { PatternModel }

At this point I’m just playing around with the concept of one-to-many. I have an express app and a controller that CRUDs the User collect without problem. My problem is when I create the first pattern. I have the following route for creating patterns.

// controllers/pattern.controller.ts
const PatternController - {
    create: async (req, res, next) => {
        try {
            const userId = req.params.userId
            req.body.user = userId
            const newPattern = await PatternModel.create(req.body)
            res
                .status(StatusCodes.CREATED)
                .json({ data: newPattern, message: ReasonPhrases.CREATED })
        } catch (error) {
            next(error)
        }
    },
}

I can create one pattern for a user. When I try to create the 2nd pattern for the same user I get

  message: 'E11000 duplicate key error collection: mycraftypal.patterns index: email_1 dup key: { email: null }',

The weird thing about the error is that I don’t have an email in the pattern.model.ts at all.

Someone can guide me in the right direction?

Hi @redeemefy ,

Well its obvious that the model doesn’t have email field but for some reason the collection does have a unique index created on that field name. If you have this index then the database will assume a null value form a non existing email field document and that cannot be duplicated…

I suspect at at some moment you might accidentally created it , just run

db.pattern.dropIndex({email : 1})

Thanks
Pavel

The index, if any, should be in the user collection since that’s the collection that has the email.unique: true. I don’t have a pattern.email property at all and I never ran any mongo command to create indexes.

Hi @redeemefy ,

If you run :

db.patterns.getIndexes()

It will tell otherwise…

So… While that’s what the question states, the code doesn’t exactly match that statement so perhaps that can be clarified a bit?

e.g. Here’s Person with a one-to-many relationship with Dog objects

const Person = {
  name: "Person",
  properties: {
    name: "string",
    birthdate: "date",
    dogs: "Dog[]"
  }
};
const Dog = {
  name: "Dog",
  properties: {
    name: "string",
    age: "int",
    breed: "string?"
  }
};

Do you want your a User to have multiple Patterns or a Pattern to have multiple Users? Or maybe something else? Or and I overlooking something?

@Jay – I want a user to have many patterns.
@Pavel_Duchovny – indeed the patterns collections has the index. I’m not sure how that got there since I never got the email property in the patterns collection.

1 Like

I had to drop the database and run the REST endpoint through postman again and that solved the issue. Now the patterns collection doesn’t have that index. Somehow that index got there.

1 Like

Hi @redeemefy ,

Its possible that you just accedently named the user element with pattern and the index got created :slight_smile: even with one run if code .

Thanks
Pavel

Probably :point_up: would be the correct solution. I just decided to drop the entire database just to make sure nothing else wrong is set.

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.