Skip to content

Commit bbc1d73

Browse files
committed
first pass at a preformant case insensitive query. mongo only so far.
1 parent 7d0d14c commit bbc1d73

File tree

4 files changed

+30
-8
lines changed

4 files changed

+30
-8
lines changed

src/Adapters/Storage/Mongo/MongoCollection.js

+14-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ export default class MongoCollection {
1313
// none, then build the geoindex.
1414
// This could be improved a lot but it's not clear if that's a good
1515
// idea. Or even if this behavior is a good idea.
16-
find(query, { skip, limit, sort, keys, maxTimeMS, readPreference } = {}) {
16+
find(
17+
query,
18+
{ skip, limit, sort, keys, maxTimeMS, readPreference, insensitive } = {}
19+
) {
1720
// Support for Full Text Search - $text
1821
if (keys && keys.$score) {
1922
delete keys.$score;
@@ -26,6 +29,7 @@ export default class MongoCollection {
2629
keys,
2730
maxTimeMS,
2831
readPreference,
32+
insensitive,
2933
}).catch(error => {
3034
// Check for "no geoindex" error
3135
if (
@@ -54,13 +58,17 @@ export default class MongoCollection {
5458
keys,
5559
maxTimeMS,
5660
readPreference,
61+
insensitive,
5762
})
5863
)
5964
);
6065
});
6166
}
6267

63-
_rawFind(query, { skip, limit, sort, keys, maxTimeMS, readPreference } = {}) {
68+
_rawFind(
69+
query,
70+
{ skip, limit, sort, keys, maxTimeMS, readPreference, insensitive } = {}
71+
) {
6472
let findOperation = this._mongoCollection.find(query, {
6573
skip,
6674
limit,
@@ -72,6 +80,10 @@ export default class MongoCollection {
7280
findOperation = findOperation.project(keys);
7381
}
7482

83+
if (insensitive) {
84+
findOperation = findOperation.collation({ locale: 'en_US', strength: 2 });
85+
}
86+
7587
if (maxTimeMS) {
7688
findOperation = findOperation.maxTimeMS(maxTimeMS);
7789
}

src/Adapters/Storage/Mongo/MongoStorageAdapter.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ export class MongoStorageAdapter implements StorageAdapter {
592592
className: string,
593593
schema: SchemaType,
594594
query: QueryType,
595-
{ skip, limit, sort, keys, readPreference }: QueryOptions
595+
{ skip, limit, sort, keys, readPreference, insensitive }: QueryOptions
596596
): Promise<any> {
597597
schema = convertParseSchemaToMongoSchema(schema);
598598
const mongoWhere = transformWhere(className, query, schema);
@@ -624,6 +624,7 @@ export class MongoStorageAdapter implements StorageAdapter {
624624
keys: mongoKeys,
625625
maxTimeMS: this._maxTimeMS,
626626
readPreference,
627+
insensitive,
627628
})
628629
)
629630
.then(objects =>

src/Controllers/DatabaseController.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,7 @@ class DatabaseController {
12101210
// acl restrict this operation with an ACL for the provided array
12111211
// of user objectIds and roles. acl: null means no user.
12121212
// when this field is not present, don't do anything regarding ACLs.
1213+
// insensitive make string comparisons case insensitive
12131214
// TODO: make userIds not needed here. The db adapter shouldn't know
12141215
// anything about users, ideally. Then, improve the format of the ACL
12151216
// arg to work like the others.
@@ -1227,6 +1228,7 @@ class DatabaseController {
12271228
distinct,
12281229
pipeline,
12291230
readPreference,
1231+
insensitive = false,
12301232
}: any = {},
12311233
auth: any = {},
12321234
validSchemaController: SchemaController.SchemaController
@@ -1271,7 +1273,14 @@ class DatabaseController {
12711273
sort.updatedAt = sort._updated_at;
12721274
delete sort._updated_at;
12731275
}
1274-
const queryOptions = { skip, limit, sort, keys, readPreference };
1276+
const queryOptions = {
1277+
skip,
1278+
limit,
1279+
sort,
1280+
keys,
1281+
readPreference,
1282+
insensitive,
1283+
};
12751284
Object.keys(sort).forEach(fieldName => {
12761285
if (fieldName.match(/^authData\.([a-zA-Z0-9_]+)\.id$/)) {
12771286
throw new Parse.Error(

src/RestWrite.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -642,11 +642,11 @@ RestWrite.prototype._validateUserName = function() {
642642
.find(
643643
this.className,
644644
{
645-
username: { $regex: `^${this.data.username}$`, $options: 'i' },
645+
username: this.data.username,
646646
objectId: { $ne: this.objectId() },
647647
_auth_data_anonymous: null,
648648
},
649-
{ limit: 1 },
649+
{ limit: 1, insensitive: true },
650650
{},
651651
this.validSchemaController
652652
)
@@ -691,10 +691,10 @@ RestWrite.prototype._validateEmail = function() {
691691
.find(
692692
this.className,
693693
{
694-
email: { $regex: `^${this.data.email}$`, $options: 'i' },
694+
email: this.data.email,
695695
objectId: { $ne: this.objectId() },
696696
},
697-
{ limit: 1 },
697+
{ limit: 1, insensitive: true },
698698
{},
699699
this.validSchemaController
700700
)

0 commit comments

Comments
 (0)