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

Update mongoose 8 #439

Merged
merged 26 commits into from
Nov 15, 2023
Merged

Update mongoose 8 #439

merged 26 commits into from
Nov 15, 2023

Conversation

meabed
Copy link
Contributor

@meabed meabed commented Nov 2, 2023

Hey @nodkz, Hope all is well, this PR to support mongoose 8 as it was release few days ago

Summary of the changes:

  • Update to mongoose 8
  • Drop node 14 testing ( and support in package.json )
  • Drop mongoose 5 testing and support
  • Upgrade tests to support mongoose 8
  • Update github actions
  • Update all packages

PR Testing are here: meabed#3

Pending Mongoose fix release: mongoose changed slightly the order of the index attributes when it has an alias - so the order for sorting enum is failing in the test.

I have a workaround already implemented to patch the index method

and the PR landed in mongoose we can remove it : I have a PR in mongoose to fix it Automattic/mongoose#14042

@meabed meabed marked this pull request as ready for review November 2, 2023 19:15
@meabed meabed changed the title WIP: Update mongoose 8 Update mongoose 8 Nov 2, 2023
@meabed
Copy link
Contributor Author

meabed commented Nov 2, 2023

Hi @nodkz this PR is ready now ✅ - would you please have a look - we might as well increase the version to major to address the dropping support of nodejs 14 and mongoose 5.

Even node16 is EOL, and Mongoose 6 is EOL too

Copy link
Member

@nodkz nodkz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @meabed it great PR! Really impressive work. 👍

@@ -90,7 +90,7 @@ describe('Resolver helper `filter` ->', () => {
const itc = args.filter.type as InputTypeComposer;
expect(itc.hasField('_id')).toBe(true);
expect(itc.hasField('name')).toBe(true);
expect(itc.hasField('age')).toBe(false);
expect(itc.hasField('age')).toBe(true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ouch, tricky case!

If client makes query with name and age then YES this mongo query will be fast.

But if be requested only age then NO this query will be slow, because this field on the second place of compound index.

And I don't know what behavior is better...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compound index will only be used if both fields request together, so it will only work on sort

On normal query with one field ( name or age ) the compound index will not be used.

So the correct solution will be actually no filters if no singular index for the field.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I suggest either keep them both or remove them both.

Currently they are both there which i think it's fine.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compound index will only be used if both fields request together

Sorry, but this statement is incorrect. Mongodb can use fields partially from compound index (from left to right).

Screenshot 2023-11-06 at 10 12 13

https://www.mongodb.com/docs/manual/core/indexes/index-types/index-compound/

So for compound index ({name:1, age: 1}) a query with filter:

  • ({ name: 'ABC', age: 33 }) will use this index
  • ({ name: 'ABC' }) will use this index
  • ({ age: 33 }) will NOT use this index

So name can be present in filter GraphQL type at any case. But age is tricky because it will work fast only if client also requested a name. And it's sad that with GraphQL is quite difficult to construct such conditional types.

Anyway, I think we can keep your change and publish under major version.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yea thank you for highlighting it!

I could make the first field of the compound index available if you prefer.

It also maybe worth mention this in the readme to make sure users understand index behavior and how best they get the queries.

);
}

const oldMongooseSchemaIndexDef = mongoose.Schema.prototype.index;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is mongoose patching is crucial? Can we find another solution to avoid modifying alien module?

With such thing we can get a security violation.

Copy link
Contributor Author

@meabed meabed Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I don't like this method - but was the only way to modify this method.

I have PR in mongoose here: Automattic/mongoose#14042

Seems it will take time to merge - and the issue will be still the issue will be in 7 and older versions - so I would suggest keeping this patch.

The patching is very small as well and if mongoose changed we can update to remove it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not create the correct index right away in the developer code?
Aliases are mongoose doc/code/operational level helpers. Indexes are DB/storage/data level staff. And mix aliases with indexes might bring a lot of headache on huge databases - it's quite easy rename alias in code, but it quite difficult to create/rename the real index in database. On my opinion, to be error prone protected it's better keep away aliases from indexes.

const UserSchema = new Schema(
  {
    n: {
      type: String,
      alias: 'name',
    },
    age: {
      type: Number,
    }
  }
)

- UserSchema.index({ name: 1, age: -1 });
+ UserSchema.index({ n: 1, age: -1 });

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, this case only happen with aliases :) however if its working now I think it's good to keep it 😄

@codecov-commenter
Copy link

codecov-commenter commented Nov 6, 2023

Codecov Report

Attention: 11 lines in your changes are missing coverage. Please review.

Comparison is base (91cdfd0) 92.54% compared to head (acc33b2) 91.67%.
Report is 5 commits behind head on master.

❗ Current head acc33b2 differs from pull request most recent head bc859d9. Consider uploading reports for the commit bc859d9 to get more accurate results

Files Patch % Lines
src/resolvers/removeMany.ts 0.00% 7 Missing ⚠️
src/fieldsConverter.ts 91.66% 1 Missing ⚠️
src/resolvers/helpers/validate.ts 80.00% 0 Missing and 1 partial ⚠️
src/resolvers/removeById.ts 75.00% 1 Missing ⚠️
src/resolvers/removeOne.ts 75.00% 1 Missing ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #439      +/-   ##
==========================================
- Coverage   92.54%   91.67%   -0.87%     
==========================================
  Files          57       57              
  Lines        2213     2283      +70     
  Branches      665      729      +64     
==========================================
+ Hits         2048     2093      +45     
- Misses        163      187      +24     
- Partials        2        3       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@loci-admin
Copy link

Amazing works @meabed hopefully we will have this enhancement release soon.

@meabed
Copy link
Contributor Author

meabed commented Nov 13, 2023

@nodkz do you think anything pending for this to be released?

meabed and others added 2 commits November 14, 2023 13:28
```diff
- UserSchema.index({ name: 1, age: -1 });
+ UserSchema.index({ n: 1, age: -1 });
```
@nodkz
Copy link
Member

nodkz commented Nov 15, 2023

@meabed could you please review my last commit 2b80ad2 ?

I dislike the idea of using some patches in runtime for instances of 3rd code/packages. So I revised all logic and found the root of our problem - incorrect use of fieldname in compound index of User mock:

const UserSchema = new Schema(
    n: {
      type: String,
      required: true,
      description: 'Person name',
      alias: 'name',
    },
);
- UserSchema.index({ name: 1, age: -1 });
+ UserSchema.index({ n: 1, age: -1 });

So it's error-prone to use aliases (name) inside compound indexes. Must be used the real field name (n) like it is in database.

I made appropriate changes in src/utils/getIndexesFromModel.ts and now it works with Mongoose 6, 7, 8.

@meabed
Copy link
Contributor Author

meabed commented Nov 15, 2023

Sounds good 😌 also my pr in mongoose is merged

@nodkz nodkz merged commit 32bb8e5 into graphql-compose:master Nov 15, 2023
4 checks passed
@nodkz
Copy link
Member

nodkz commented Nov 15, 2023

@meabed thank you a lot for the gorgeous PR 💪

@meabed
Copy link
Contributor Author

meabed commented Nov 15, 2023

Thank you @nodkz I have upgraded and tested 🚀 all looks great :)

Also the PR for index order in mongoose has been released: https://github.com/Automattic/mongoose/releases/tag/8.0.1

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

Successfully merging this pull request may close these issues.

None yet

4 participants