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

Robust handling of ObjectID type for MongoDB #3720

Open
bajtos opened this issue Sep 12, 2019 · 2 comments
Open

Robust handling of ObjectID type for MongoDB #3720

bajtos opened this issue Sep 12, 2019 · 2 comments
Labels
epic major Repository Issues related to @loopback/repository package

Comments

@bajtos
Copy link
Member

bajtos commented Sep 12, 2019

MongoDB is tricky - see #1875

  • It uses a custom ObjectID type for primary keys.
  • ObjectID is represented as a string when converted to JSON
  • In queries, string values must be cast to ObjectID, otherwise they are not considered as the same value: 'some-id' !== ObjectID('some-id').

As a result, both PK and FK properties must use ObjectID as the type, and coercion must be applied where necessary.

Ideally, I'd like LB4 to define MongoDB PK and FKs as follows:

  • {type: 'string', mongodb: {dataType: 'ObjectID'}}

Even better, dataType: 'ObjectID' should be automatically applied by the connector for PK and FKs referencing ObjectID PKs.

For example:

@model()
class Product {
  @property({
    type: 'string',
    generated: true,
    // ^^ implies dataType: 'ObjectID'
  })
  id: string;

  @property({
    type: 'string',
    references: {
      model: () => Category,
      property: 'id',
    },
    // ^^ implies dataType: 'ObjectID' when Category is attached to MongoDB
  })
  categoryId: string;
}

For v1, I suppose we can ask developers to provide dataType manually.

@model()
class Product {
  @property({
    type: 'string',
    generated: true,
    mongodb: {dataType: 'ObjectID'},
  })
  id: string;

  @property({
    type: 'string',
    mongodb: {dataType: 'ObjectID'},
  })
  categoryId: string;
}

With this setup in place, id and categoryId properties should be always returned as strings from DAO and connector methods.

Related discussions

Acceptance criteria

  • For every property defined as {type: 'string', mongodb: {dataType: 'ObjectID'}}, including properties defined in nested/embedded models:

    • When the MongoDB connector returns data from database, it converts ObjectID values to strings.
    • When the MongoDB connector writes data to database, it converts string values to ObjectID
    • When the MongoDB connector queries database (think of filter.where, but also findById and replaceById), it converts string values to ObjectID. The conversion is applied to non-trivial conditions too, e.g. {where: {id: { inq: ['my-objectid-1', 'my-objectid-2'] }}}
  • Documentation page for MongoDB users explaining extra configuration needed

  • Blog post announcing the improvements

Tasks

@sushant022
Copy link

Loopback 3 has AccessToken _id of type string.
I have an app using db generated by lb3 and reuse in an lb4 app.
How can i use _id as type string?

@Barnette-ao
Copy link

Barnette-ao commented Aug 31, 2022

there is something confused by setting mongodb: {dataType: 'ObjectID'}, in my loopback4 application.

When the MongoDB connector returns data from database, it converts ObjectID values to strings.

as above say, if I get a model User,and I call the this.userRepository.create(user),it will return a User object instance,UserInstance.

Expect

according to my understand of citing criteria,I expect

typeof(UserInstance.id) == string

Actural

typeof(UserInstance) == object

this make me confused about the criteria cited above.

please give me some instruction.

@bajtos

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
epic major Repository Issues related to @loopback/repository package
Projects
None yet
Development

No branches or pull requests

4 participants