feat: allows like to search by many words, adds contain to match exact strings

This commit is contained in:
James
2022-04-05 16:22:57 -04:00
parent b99f6b16af
commit ec91757257
5 changed files with 35 additions and 18 deletions

View File

@@ -59,7 +59,8 @@ The above example demonstrates a simple query but you can get much more complex.
| `greater_than_equal` | For numeric or date-based fields. |
| `less_than` | For numeric or date-based fields. |
| `less_than_equal` | For numeric or date-based fields. |
| `like` | The value must partially match. |
| `like` | Case-insensitive string must be present. If string of words, all words must be present, in any order. |
| `contains` | Must contain the value entered, case-insensitive. |
| `in` | The value must be found within the provided comma-delimited list of values. |
| `not_in` | The value must NOT be within the provided comma-delimited list of values. |
| `exists` | Only return documents where the value either exists (`true`) or does not exist (`false`). |

View File

@@ -62,26 +62,31 @@ const like = {
value: 'like',
};
const contains = {
label: 'contains',
value: 'contains',
};
const fieldTypeConditions = {
text: {
component: 'Text',
operators: [...base, like],
operators: [...base, like, contains],
},
email: {
component: 'Text',
operators: [...base, like],
operators: [...base, contains],
},
textarea: {
component: 'Text',
operators: [...base, like],
},
wysiwyg: {
component: 'Text',
operators: [...base, like],
operators: [...base, like, contains],
},
code: {
component: 'Text',
operators: [...base, like],
operators: [...base, like, contains],
},
richText: {
component: 'Text',
operators: [...base, like, contains],
},
number: {
component: 'Number',

View File

@@ -44,7 +44,7 @@ const fieldToSchemaMap: (parentName: string) => any = (parentName: string) => ({
field,
type,
parentName,
[...operators.equality, 'like'],
[...operators.equality, 'like', 'contains'],
),
};
},
@@ -55,7 +55,7 @@ const fieldToSchemaMap: (parentName: string) => any = (parentName: string) => ({
field,
type,
parentName,
[...operators.equality, 'like'],
[...operators.equality, 'like', 'contains'],
),
};
},
@@ -66,7 +66,7 @@ const fieldToSchemaMap: (parentName: string) => any = (parentName: string) => ({
field,
type,
parentName,
[...operators.equality, 'like'],
[...operators.equality, 'like', 'contains'],
),
};
},
@@ -77,7 +77,7 @@ const fieldToSchemaMap: (parentName: string) => any = (parentName: string) => ({
field,
type,
parentName,
[...operators.equality, 'like'],
[...operators.equality, 'like', 'contains'],
),
};
},
@@ -88,7 +88,7 @@ const fieldToSchemaMap: (parentName: string) => any = (parentName: string) => ({
field,
type,
parentName,
[...operators.equality, 'like'],
[...operators.equality, 'like', 'contains'],
),
};
},
@@ -116,7 +116,7 @@ const fieldToSchemaMap: (parentName: string) => any = (parentName: string) => ({
}, {}),
}),
parentName,
[...operators.equality, 'like'],
[...operators.equality, 'like', 'contains'],
),
}),
date: (field: DateField) => {

View File

@@ -8,7 +8,7 @@ import { getSchemaTypeOptions } from './getSchemaTypeOptions';
import { operatorMap } from './operatorMap';
import { sanitizeQueryValue } from './sanitizeFormattedValue';
const validOperators = ['like', 'in', 'all', 'not_in', 'greater_than_equal', 'greater_than', 'less_than_equal', 'less_than', 'not_equals', 'equals', 'exists', 'near'];
const validOperators = ['like', 'contains', 'in', 'all', 'not_in', 'greater_than_equal', 'greater_than', 'less_than_equal', 'less_than', 'not_equals', 'equals', 'exists', 'near'];
const subQueryOptions = {
limit: 50,

View File

@@ -90,8 +90,19 @@ export const sanitizeQueryValue = (schemaType: SchemaType, path: string, operato
}
}
if (operator === 'like' && path !== '_id') {
formattedValue = { $regex: formattedValue, $options: 'i' };
if (path !== '_id') {
if (operator === 'contains') {
formattedValue = { $regex: formattedValue, $options: 'i' };
}
if (operator === 'like' && typeof formattedValue === 'string') {
const words = formattedValue.split(' ');
const regex = words.reduce((pattern, word, i) => {
return `${pattern}(?=.*\\b${word}\\b)${i + 1 === words.length ? '.+' : ''}`;
}, '');
formattedValue = { $regex: new RegExp(regex), $options: 'i' };
}
}
if (operator === 'exists') {