fix(176): split fulltext matches/notMatches from text contains
This commit is contained in:
@@ -18,6 +18,11 @@ describe('compile', () => {
|
||||
expect(compile({ match: 'all', children: [{ field: 'title', operator: 'startsWith', value: 'The' }] })).toBe('title:The*');
|
||||
});
|
||||
|
||||
it('quotes fulltext matches / notMatches (distinct from text contains)', () => {
|
||||
expect(compile({ match: 'all', children: [{ field: 'plot', operator: 'matches', value: 'car chase' }] })).toBe('plot:"car chase"');
|
||||
expect(compile({ match: 'all', children: [{ field: 'plot', operator: 'notMatches', value: 'car' }] })).toBe('NOT plot:"car"');
|
||||
});
|
||||
|
||||
it('emits numeric ranges', () => {
|
||||
expect(compile({ match: 'all', children: [{ field: 'minutes', operator: 'gt', value: '30' }] })).toBe('minutes:{30 TO *}');
|
||||
expect(compile({ match: 'all', children: [{ field: 'minutes', operator: 'lt', value: '90' }] })).toBe('minutes:{* TO 90}');
|
||||
|
||||
@@ -15,15 +15,15 @@ function compileRule(rule: Rule): string {
|
||||
const v = rule.value;
|
||||
switch (rule.operator) {
|
||||
case 'is':
|
||||
case 'matches': // fulltext: same quoted form as text `is`, disambiguated by field type on parse
|
||||
return `${f}:${quote(v)}`;
|
||||
case 'isNot':
|
||||
case 'notMatches':
|
||||
return `NOT ${f}:${quote(v)}`;
|
||||
case 'contains':
|
||||
return `${f}:*${escapeWild(v)}*`;
|
||||
case 'startsWith':
|
||||
return `${f}:${escapeWild(v)}*`;
|
||||
case 'notContains':
|
||||
return `NOT ${f}:${quote(v)}`;
|
||||
case 'eq':
|
||||
return `${f}:${v}`;
|
||||
case 'gt':
|
||||
|
||||
@@ -2,9 +2,10 @@ export type FieldType = 'text' | 'fulltext' | 'number' | 'date' | 'enum';
|
||||
export type Match = 'all' | 'any';
|
||||
|
||||
export type Operator =
|
||||
| 'is' | 'isNot' | 'contains' | 'startsWith' | 'notContains'
|
||||
| 'eq' | 'gt' | 'lt' | 'between'
|
||||
| 'before' | 'after';
|
||||
| 'is' | 'isNot' | 'contains' | 'startsWith' // text
|
||||
| 'matches' | 'notMatches' // fulltext
|
||||
| 'eq' | 'gt' | 'lt' | 'between' // number
|
||||
| 'before' | 'after'; // date
|
||||
|
||||
export interface Rule {
|
||||
field: string;
|
||||
@@ -25,7 +26,7 @@ export function isGroup(node: Rule | Group): node is Group {
|
||||
// Which fields each catalog type exposes as operators (used by the UI and tests).
|
||||
export const OPERATORS_BY_TYPE: Record<FieldType, Operator[]> = {
|
||||
text: ['is', 'isNot', 'contains', 'startsWith'],
|
||||
fulltext: ['contains', 'notContains'],
|
||||
fulltext: ['matches', 'notMatches'],
|
||||
enum: ['is', 'isNot'],
|
||||
number: ['eq', 'gt', 'lt', 'between'],
|
||||
date: ['before', 'after', 'between']
|
||||
|
||||
Reference in New Issue
Block a user