Skip to content
This repository has been archived by the owner on Mar 15, 2023. It is now read-only.

Add support for MongoDB collation. #79

Merged
merged 2 commits into from
Jan 7, 2017
Merged

Add support for MongoDB collation. #79

merged 2 commits into from
Jan 7, 2017

Conversation

JoshuaToenyes
Copy link
Contributor

This PR adds MongoDB collation support to the find, remove and patch methods. Using collations, it's possible to perform case-insensitive and locale-aware queries.

I'm not sure what the built-in version of MongoDB is on Travis CI. This PR will likely fail to build if using < v3.4. See Potential Problems below.

MongoDB introduced collation support in v3.4 see the Release Notes for MongoDB 3.4 – Collation and Case Insensitive Indexes for more information on the feature.

This pull request implements collation support via a collation parameter passed to find(), remove() and patch(). Tests are included in this PR, but here are some quick examples on how this could be used:

Example: Patch records with case-insensitive alphabetical ordering.

The example below would patch all student records with grades of "c" or "C" and above (a natural language ordering). Without collations this would not be as simple, since the comparison { $gt: "c" } would not include uppercase grades of "C" because the binary codepoint of "C" is less than "c".

const patch = { shouldStudyMore: true };
const query = { grade: { $gte: "c" } };
const collation = { locale: "en", strength: 1 };
students.patch(null, patch, { query, collation }).then( ... );

Example: Find records with a case-insensitive search.

Similar to the above example, this would find poor students by their grades, in a case-insensitive manner.

const query = { grade: { $gte: "c" } };
const collation = { locale: "en", strength: 1 };
students.find({ query, collation }).then( ... );

Potential Problems

One potential problem I see with the update() method, is that a collation member must be added to the query passed to MongoDB. MongoDB's documentation on this is a little vague... it seems that you would set the collation member on the option parameter, but that does not work. This could lead to a collision when updating records with a collation member. I'm open to suggestions on how to solve this. Since MongoDB v3.4 is so young, there's not a lot of discourse available on the best way to uses these new features.

Another potential issue is that the collation support is (obviously) not available on MongoDB version < v3.4. It would be nice to throw an error if someone attempts to use the collation parameter with an older version of MongoDB. But... only a reference to the collection is passed to the service, which precludes checking the db version without hacking a reference to the parent db instance through the collection. I'm not a MongoDB ace–maybe there's a simple way to check the MongoDB version that I'm unaware of.

- Disclaimer -

I've implemented collation as a parameter because to me, that seems like the most natural way to use it. I'm relatively new to using Feathers... and I know one of the main selling points of using Feathers is the ability to "drop-in" other storage engines. So I'm not sure if there's a philosophical resistance to implementing database-specific features. It seems, however, that other database adapters do exactly that (KnexJS for example, implements a special $like filter). If there's a more appropriate way of implementing this feature, please let me know. I'd be glad to modify the PR.

@daffl
Copy link
Member

daffl commented Dec 23, 2016

Could we maybe get it to work with MongoDB 3 by adding

addons:
  apt:
    sources:
      - mongodb-upstart
      - mongodb-3.0-precise
    packages:
      - mongodb-org-server
      - mongodb-org-shell

before_script:
  - sleep 15

Taken from here

@JoshuaToenyes
Copy link
Contributor Author

Got it to build using the apt addon for Travis CI and adding sourceline config from Mongo's Installing Packages with APT documentation.

See also Travis CI's documentation on Installing Packages with APT Addon.

@JoshuaToenyes
Copy link
Contributor Author

Travis CI is pretty far behind on MongoDB support; it's still running 2.x. (travis-ci/travis-ci#3694)

Personally, I think it makes sense to build on v3.4 for this project.

@daffl
Copy link
Member

daffl commented Dec 23, 2016

Awesome! Yeah, it uses some really strange old version of Firefox, too so I'm not surprised. I'll review the rest of the PR in the next few days. We already have a params.mongodb but I think it makes sense to add this parameter because it is not covered by that yet.

@JoshuaToenyes
Copy link
Contributor Author

Sweet. Thank you. I did see the params.mongodb.

I suppose another option could be to pull the collation member off of params.mongodb instead of having it as a separate parameter.

@JoshuaToenyes
Copy link
Contributor Author

Any thoughts on this @daffl? I'd like to start using the main package, instead of a private fork :) Let me know if you'd like me to change it to pull collation off of params.mongodb.

@daffl
Copy link
Member

daffl commented Jan 7, 2017

@JoshuaToenyes Sorry about that. This looks great. I think keeping it directly in params is fine (since params.mongodb is specifically for the MongoDB options). I'll release this as a minor version. Could you add documentation for it in https://github.com/feathersjs/feathers-docs/edit/auk/databases/mongodb.md?

@daffl daffl merged commit 7aea44a into feathersjs-ecosystem:master Jan 7, 2017
@JoshuaToenyes
Copy link
Contributor Author

Awesome. Thanks for merging! Yes, I'll fork and update the docs.

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

Successfully merging this pull request may close these issues.

2 participants