Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to save document without define an _id in his model #7542

Closed
Royalsspirit opened this issue Feb 20, 2019 · 9 comments
Closed

Failed to save document without define an _id in his model #7542

Royalsspirit opened this issue Feb 20, 2019 · 9 comments

Comments

@Royalsspirit
Copy link

Royalsspirit commented Feb 20, 2019

Do you want to request a feature or report a bug?
Report a bug introduice since 5.4.11

What is the current behavior?
Since 5.4.11, an error occure when i want to save this document:

const mongoose = require('mongoose');

const myModel = new mongoose.Schema({
  query: {
    type: String,
    required: true,
  },
  user: {
    _id: false,
    name: {
      type: String,
      required: true,
    },
    firstname: {
      type: String,
      required: true,
    },
  },
  params: [
    {
      _id: false,
      name: {
        type: String,
        required: true,
      },
    },
  ],
  dateCreated: {
    type: Date,
    trim: true,
    default: Date.now,
  },
});

const model = mongoose.model('myModel', myModel);
const query = "I want this";
const params = [{"name":"with this"}];
const user= {"name":"toto", "firstname":"toto"};
const obj = {
    query,
    params,
    user
}
const response = new model(obj)
response.save(error => (error ? next(error) : res.send({ success: true })));

It's like mongoose don't generate an _id by default like in previous version.

I tried many things to fix the issue and i found that when i remove _id:false from user. I get what i expected or an other way is to define a _id in main document like

  _id: {
    type: mongoose.Schema.Types.ObjectId,
    required: true,
    auto: true,
  },

If the current behavior is a bug, please provide the steps to reproduce.

  • install the last version of mongoose
  • code above will failed but if you go back to 5.4.10. it works

What is the expected behavior?
Expect document has been created but have document must have an _id before saving mongooseError without any unique ID in my model but it worked before 5.4.10

Please mention your node.js, mongoose and MongoDB version.
node: v9.0.0
mongodb: v4.0.0
mongoose: v5.4.14

@mhombach
Copy link

I might misunderstand your issue but be aware of this:
In MongoDB (as in most likely every Database) EVERY document/entry must have a unuqie identifier, so that the Database can explicitly target that entry.

If a document does not have a value for the indexed field in a unique index, the index will store a null value for this document. Because of the unique constraint, MongoDB will only permit one document that lacks the indexed field. If there is more than one document without a value for the indexed field or is missing the indexed field, the index build will fail with a duplicate key error.
( Source: https://docs.mongodb.com/manual/core/index-unique )

So you MUST create some unique field because otherwise there could exist 2 or more document with the exact same attributes/values. And if that's the case, you and mongoDB are unable to target one entry without the other.

I hope this helps to clear things up for you.
If there is still another issue and i maybe didn't get what you asked for, please try to redefine your question :)

@Royalsspirit
Copy link
Author

Royalsspirit commented Feb 21, 2019

Hello mhombach, thank you for your reply.
I think, you understand my issue, i know that each documents must have an unique ID but in previous version 5.4.11, i didn't have to explicitly define it. It was like _id was defined by default.

I'im just wondering, if lastest version changed something about that.

@mhombach
Copy link

mhombach commented Feb 21, 2019

The _id is generated with an objectId by default, even when not defining that field.
You can change the field by defining it like for example _id: String. If you do that, you yourself have to take care of creating unique strings beeing used for that field.

There is an exception:
On SUB-Documents you can disable the default generation of id-fields by writing:

var subSchema = mongoose.Schema({
    //your subschema content
},{ _id : false });

On first glance this might seem irritating, but you have to keep in mind the difference between mongoose and MongoDB.
SUB-Documents are not "real" documents in mongodb. The "most parent" document is the "real" document (which is the "model" in mongoose).
SUB-documents are, inside the mongo-database, only objects with sub-attributes. A MongoDB-Query will retur na document and NOT a sub-document. So if you have an array of subdocuments in your parent one and you cannot explicitly target a specific subdocument because there is no _id, then for mongoDb this is no problem, because the document (parent one) is still targetable by the _id.

I don't think that this has changed in mongoose like.... ever....
So i think that you most likely did some other changes you were not aware of (switching document and SUB-document for example when re-designing your data-structure) :)

EDIT:
I might have found your problem:
You are defining the _id: false, on the wrong place.
Like in my given JS-example, you need to tell mongoose about this setting in a SECOND object in your schema. I am using a different style of defining my schemas, so you might want to look up how this is written in your example.

@Royalsspirit
Copy link
Author

After reading your reply, i think i understood my problem.

SUB-Documents are not "real" documents in mongodb. The "most parent" document is the "real" document (which is the "model" in mongoose).

Yes, that's it ! I tought that my field params was considering as a subdocument but it's not (it's just a field :p). That's why i put _id: false in all fields define as object or array.

Otherwise, if i define params content as model and i put it in main model as subdocument. I have to set _id: false in second object parameter to not have _id as you said and as we can see here

In this situation, when _id: false is in wrong place, latest mongoose version is maybe more restrective than previous version.

Again, thank you for your time and your help mhombach

@mhombach
Copy link

Glad we figured your probleme out :)
I still think that some lines in your code changed between the mongoose-versions, because the handling of _id is very fundamental and should be coded into mongoose from the beginning... But well, your problem is solved, that' what counts =)
If you don't have any questions left, could you please close this issue? So other users, that want to help, can focus on other open issues ^^

@Royalsspirit
Copy link
Author

I still think that some lines in your code changed between the mongoose-versions, because the handling of _id is very fundamental and should be coded into mongoose from the beginning...

I'm just saying, the latest version is maybe more restrective regarding model syntax since we conclude that i put _id:false in wrong place for params field

I have not changed anything between mongoose version. With the model i showed you, this issue is gone when i come back to 5.4.10 and occure with the latest.

Anyway, we found a solution to fix document must have an _id before saving in this case. I'm going to close this issue.

@mhombach
Copy link

Hmm... ok, if you checked that the same code produces different behaviour with just the versions changing, then you maybe should create a new issue with that in focus. With a small script to reproduce the difference, maybe maintainers can check if this is wanted behaviour or not :)

@vkarpov15
Copy link
Collaborator

@mhombach You're right about _id in the wrong place. However, this issue has nothing to do with the user failing to create an _id, they should not have to in this case because they aren't disabling _id on the top level schema

@Royalsspirit there will be a fix for this issue in 5.4.16, this issue was also reported in #7524. Please see my comments here: #7524 (comment)

@Royalsspirit
Copy link
Author

@vkarpov15 Thank you very much for your reply.
So it was a reel issue even if i found it in incorrect schema declaration. Now i know how to disabled _id properly :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants