From 4dd703a6bff0ab7d06af234baa975553bd62f176 Mon Sep 17 00:00:00 2001 From: James Date: Mon, 19 Jun 2023 10:13:47 -0400 Subject: [PATCH] fix: slow like queries with lots of records --- src/mongoose/buildQuery.ts | 17 +++++++++++++++++ src/mongoose/sanitizeQueryValue.ts | 6 ------ test/collections-rest/int.spec.ts | 16 ++++++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/mongoose/buildQuery.ts b/src/mongoose/buildQuery.ts index 3e09feab23..c88c885ad3 100644 --- a/src/mongoose/buildQuery.ts +++ b/src/mongoose/buildQuery.ts @@ -372,6 +372,23 @@ export class ParamParser { } } + if (operator === 'like' && typeof formattedValue === 'string') { + const words = formattedValue.split(' '); + + const result = { + value: { + $and: words.map((word) => ({ + [path]: { + $regex: word.replace(/[\\^$*+?\\.()|[\]{}]/g, '\\$&'), + $options: 'i', + }, + })), + }, + }; + + return result; + } + // Some operators like 'near' need to define a full query // so if there is no operator key, just return the value if (!operatorKey) { diff --git a/src/mongoose/sanitizeQueryValue.ts b/src/mongoose/sanitizeQueryValue.ts index 4934e25a7a..00eedc8f30 100644 --- a/src/mongoose/sanitizeQueryValue.ts +++ b/src/mongoose/sanitizeQueryValue.ts @@ -1,6 +1,5 @@ import mongoose from 'mongoose'; import { createArrayFromCommaDelineated } from './createArrayFromCommaDelineated'; -import wordBoundariesRegex from '../utilities/wordBoundariesRegex'; import { Field, TabAsField } from '../fields/config/types'; type SanitizeQueryValueArgs = { @@ -107,11 +106,6 @@ export const sanitizeQueryValue = ({ field, path, operator, val, hasCustomID }: if (operator === 'contains') { formattedValue = { $regex: formattedValue, $options: 'i' }; } - - if (operator === 'like' && typeof formattedValue === 'string') { - const $regex = wordBoundariesRegex(formattedValue); - formattedValue = { $regex }; - } } if (operator === 'exists') { diff --git a/test/collections-rest/int.spec.ts b/test/collections-rest/int.spec.ts index 47a3aa2dd8..6d402a3f5d 100644 --- a/test/collections-rest/int.spec.ts +++ b/test/collections-rest/int.spec.ts @@ -648,6 +648,22 @@ describe('collections-rest', () => { expect(result.totalDocs).toEqual(1); }); + it('like - cyrillic characters in multiple words', async () => { + const post1 = await createPost({ title: 'привет, это тест полезной нагрузки' }); + + const { status, result } = await client.find({ + query: { + title: { + like: 'привет нагрузки', + }, + }, + }); + + expect(status).toEqual(200); + expect(result.docs).toEqual([post1]); + expect(result.totalDocs).toEqual(1); + }); + it('like - partial word match', async () => { const post = await createPost({ title: 'separate words should partially match' });