Text search
Search text fields with the find operator. Wrap the search term in slashes, like /shoe/, to match it anywhere in the value (the text between the slashes is a regular expression), and set regexFlags to i for case-insensitive search. Without slashes, find compares the whole value exactly. Essential for search bars, autocomplete, and text filtering.
Syntax
list.catalog.query.addCondition({
attribute: string,
operator: 'find',
value: string | object, // '/term/' = contains, 'term' = exact, { brand: 'Apple' } = partial object match
options?: SearchOptions
})Parameters
attributestringRequired- The text field to search in
operator'find'Required- The find operator for text and pattern matching
valuestring | objectRequired- /term/ matches the term anywhere in the value (regex); a bare term without slashes must equal the whole value. An object matches part of a json value ({ brand: 'Apple' }), see the Query Operators Reference
options.regexFlagsstringOptional- Regex flags for a '/term/' value, e.g. 'i' for case-insensitive. Put flags here, not after the closing slash ('/term/i' is an exact match)
options.transform('lowercase' | 'trim' | 'removeWhitespace')[]Optional- Transform both data and search value before comparison
options.invertbooleanOptional- Exclude matches (find items NOT containing the term). Items without a value are left out too
options.arrayValueHandling'some' | 'every'Optional- For array fields: 'some' (any element) or 'every' (all elements)
Return type
addCondition() returns the updated query (DcuplGlobalQueryOptions); call items() for the matching items:
// list.catalog.query
addCondition(condition: DcuplQuery | DcuplQuery[]): DcuplGlobalQueryOptions<any>; // the list's query
items(options?: DcuplListQueryOptions<T>): T[];Usage notes
- '/phone/' matches "Smartphone" and "headphones", not "Phone Case"; with regexFlags: 'i' it matches all three. '/^run/' with 'i' matches "Running Shoes" and "runner", not "outrun". 'Phone Case' (no slashes) matches only that whole value
- A /regex/ is tested against non-string values as strings: /^1/ on a number attribute matches 150 and 100
- Transforms: 'lowercase', 'trim' (leading/trailing whitespace) and 'removeWhitespace' (all whitespace)
- Wrap the term in slashes (/term/) for substring search; a bare string must match the whole value
- Set regexFlags to i for case-insensitive, user-facing search
- Escape regex characters (. * + ? ^ $ { } ( ) | [ ] \) in user input before wrapping it in slashes
- Transforms apply to BOTH the data value AND your search term
- Use multiple find conditions on same field for OR logic
- Combine with other operators (eq, gte) for filtered search
- For suggestions/autocomplete, see catalog.fn.suggest()
Related methods
catalog.fn.suggest()— Get value suggestions for autocomplete (case-insensitive prefix match, or a /regex/)
Related guides/docs
Examples
Substring search
Wrap the term in slashes to find products whose name contains "Bike" (case-sensitive by default).
const productList = dcupl.lists.create({ modelKey: 'Product' });
productList.catalog.query.addCondition({
attribute: 'name',
operator: 'find',
value: '/Bike/',
});
// Matches: "Mountain Bike", "Bike Helmet"
// No match: "bike lock" (case-sensitive), "Bicycle"
const results = productList.catalog.query.items();Case-insensitive search
Add regexFlags: 'i' to ignore case (recommended for user-facing search).
const productList = dcupl.lists.create({ modelKey: 'Product' });
productList.catalog.query.addCondition({
attribute: 'name',
operator: 'find',
value: '/running/',
options: { regexFlags: 'i' },
});
// Matches: "Running Shoes", "Trail Running Shoes", "running socks"
const results = productList.catalog.query.items();Search with user input
Escape regex characters in user input before wrapping it in slashes.
const productList = dcupl.lists.create({ modelKey: 'Product' });
const escapeRegExp = (text: string) => text.replace(/[.*+?^${}()|[\]\\]/g, (char) => '\\' + char);
const userInput = ' shoe ';
productList.catalog.query.addCondition({
attribute: 'name',
operator: 'find',
value: `/${escapeRegExp(userInput.trim())}/`,
options: { regexFlags: 'i' },
});
// Matches: "Running Shoes", "Trail Running Shoes", "Snowshoes"
const results = productList.catalog.query.items();Pattern search
The text between the slashes is a JavaScript regular expression, so anchors and alternation work too.
const productList = dcupl.lists.create({ modelKey: 'Product' });
// Names that start with "trail" or "mountain", any case
productList.catalog.query.addCondition({
attribute: 'name',
operator: 'find',
value: '/^(trail|mountain)/',
options: { regexFlags: 'i' },
});
// Matches: "Trail Running Shoes", "Mountain Bike"
// No match: "Bike Trailer" (does not start with it)
const results = productList.catalog.query.items();Exact match (no slashes)
A bare string compares the whole value. Transforms normalize both sides before comparing.
const productList = dcupl.lists.create({ modelKey: 'Product' });
// trim: remove leading/trailing whitespace
// removeWhitespace: remove ALL whitespace
productList.catalog.query.addCondition({
attribute: 'sku',
operator: 'find',
value: 'ABC123',
options: { transform: ['trim', 'removeWhitespace'] },
});
// Matches: " ABC 123 ", "ABC123", "A B C 1 2 3"
// No match: "ABC1234" (a bare string never matches part of a value)
const results = productList.catalog.query.items();Search multiple fields
Search name OR description by putting both conditions in one or-group.
const productList = dcupl.lists.create({ modelKey: 'Product' });
// Conditions on different attributes are combined with AND,
// so group them with groupType 'or'
productList.catalog.query.addGroup({
groupKey: 'search',
groupType: 'or',
queries: [
{ attribute: 'name', operator: 'find', value: '/waterproof/', options: { regexFlags: 'i' } },
{ attribute: 'description', operator: 'find', value: '/waterproof/', options: { regexFlags: 'i' } },
],
});
// Matches: "Waterproof Jacket", and "Hiking Boots" (described as waterproof)
const results = productList.catalog.query.items();Exclude search terms
Find products NOT containing "refurbished" using invert.
const productList = dcupl.lists.create({ modelKey: 'Product' });
productList.catalog.query.addCondition({
attribute: 'name',
operator: 'find',
value: '/refurbished/',
options: {
regexFlags: 'i',
invert: true, // Exclude matches
},
});
// Returns products without "refurbished" in the name
const newProducts = productList.catalog.query.items();Search in array fields
Find products where ANY tag contains the search term.
const productList = dcupl.lists.create({ modelKey: 'Product' });
productList.catalog.query.addCondition({
attribute: 'tags',
operator: 'find',
value: '/sale/',
options: {
regexFlags: 'i',
arrayValueHandling: 'some', // Match if ANY element contains "sale"
},
});
// Matches: tags = ["summer-sale", "clearance"]
// Matches: tags = ["new", "SALE-2024"]
const saleProducts = productList.catalog.query.items();Search with category filter
Combine text search with other filters.
const productList = dcupl.lists.create({ modelKey: 'Product' });
// Text search
productList.catalog.query.addCondition({
attribute: 'name',
operator: 'find',
value: '/pro/',
options: { regexFlags: 'i' },
});
// Combined with category filter (AND logic)
productList.catalog.query.addCondition({
attribute: 'category',
operator: 'eq',
value: 'Electronics',
});
// Result: Electronics products with "pro" in the name
const results = productList.catalog.query.items();// Case-insensitive substring search
const list = dcupl.lists.create({ modelKey: 'Article' });
// Find products whose name contains "shoe" (any case)
list.catalog.query.addCondition({
attribute: 'productName',
operator: 'find',
value: '/shoe/',
options: { regexFlags: 'i' },
});
// Get search results
const results = list.catalog.query.items();
console.log('Found:', results.length, 'matching products');[]