import { q, search } from '@codeforamerica/safety-net-colorado';
const query = q(
search.eq("status", "approved"),
search.gte("income", 1000),
search.in("programs", ["snap", "cash_programs"])
);
// => "status:approved income:>=1000 programs:snap,cash_programs"
const results = await personsClient.listPersons({
queries: { q: query, limit: 25 }
});
/
/**
Combines multiple search conditions into a single query string.
Multiple conditions are ANDed together (all must match).
Use comma-separated values within a single condition for OR logic.
## Syntax Reference
| Pattern | Description | Example |
|---------|-------------|---------|
| `term` | Full-text exact match | `john` |
| `*term*` | Full-text contains | `*john*` |
| `term*` | Full-text starts with | `john*` |
| `*term` | Full-text ends with | `*smith` |
| `field:value` | Exact match | `status:approved` |
| `field:*value*` | Contains (case-insensitive) | `name:*john*` |
| `field:value*` | Starts with | `name:john*` |
| `field:*value` | Ends with | `email:*@example.com` |
| `field:"value"` | Quoted value (for spaces) | `name:"john doe"` |
| `field.nested:value` | Nested field (dot notation) | `address.state:CA` |
| `field:>value` | Greater than | `income:>1000` |
| `field:>=value` | Greater than or equal | `income:>=1000` |
| `field:<value` | Less than | `income:<5000` |
| `field:<=value` | Less than or equal | `income:<=5000` |
| `field:val1,val2` | Match any value (OR) | `status:approved,pending` |
| `-field:value` | Exclude / negate | `-status:denied` |
| `field:*` | Field exists (not null) | `email:*` |
| `-field:*` | Field does not exist | `-deletedAt:*` |// Full-text search
q("john")
// => "john"// Exact match on a field
q("status:approved")
// => "status:approved"// Multiple conditions (AND)
q("status:approved", "income:>=1000")
// => "status:approved income:>=1000"// Using the search builder
q(search.eq("status", "approved"), search.gte("income", 1000))
// => "status:approved income:>=1000"
search.eq(): string
Search Query Helpers for Safety Net API Clients
import { q, search } from '@codeforamerica/safety-net-colorado';
const query = q(
search.eq("status", "approved"),
search.gte("income", 1000),
search.in("programs", ["snap", "cash_programs"])
);
// => "status:approved income:>=1000 programs:snap,cash_programs"
const results = await personsClient.listPersons({
queries: { q: query, limit: 25 }
});
/
/**
Combines multiple search conditions into a single query string.
Multiple conditions are ANDed together (all must match).
Use comma-separated values within a single condition for OR logic.
## Syntax Reference
| Pattern | Description | Example |
|---------|-------------|---------|
| `term` | Full-text exact match | `john` |
| `*term*` | Full-text contains | `*john*` |
| `term*` | Full-text starts with | `john*` |
| `*term` | Full-text ends with | `*smith` |
| `field:value` | Exact match | `status:approved` |
| `field:*value*` | Contains (case-insensitive) | `name:*john*` |
| `field:value*` | Starts with | `name:john*` |
| `field:*value` | Ends with | `email:*@example.com` |
| `field:"value"` | Quoted value (for spaces) | `name:"john doe"` |
| `field.nested:value` | Nested field (dot notation) | `address.state:CA` |
| `field:>value` | Greater than | `income:>1000` |
| `field:>=value` | Greater than or equal | `income:>=1000` |
| `field:<value` | Less than | `income:<5000` |
| `field:<=value` | Less than or equal | `income:<=5000` |
| `field:val1,val2` | Match any value (OR) | `status:approved,pending` |
| `-field:value` | Exclude / negate | `-status:denied` |
| `field:*` | Field exists (not null) | `email:*` |
| `-field:*` | Field does not exist | `-deletedAt:*` |
// Full-text search
q("john")
// => "john"
// Exact match on a field
q("status:approved")
// => "status:approved"
// Multiple conditions (AND)
q("status:approved", "income:>=1000")
// => "status:approved income:>=1000"
// Using the search builder
q(search.eq("status", "approved"), search.gte("income", 1000))
// => "status:approved income:>=1000"
search.gt(): string
Greater than: `field:>value`
search.gt("income", 1000)
// => "income:>1000"
search.gte(): string
Greater than or equal: `field:>=value`
search.gte("income", 1000)
// => "income:>=1000"
search.lt(): string
Less than: `field:<value`
search.lt("age", 65)
// => "age:<65"
search.lte(): string
Less than or equal: `field:<=value`
search.lte("income", 5000)
// => "income:<=5000"
search.in(): string
Match any of the values (OR): `field:val1,val2,val3`
search.in("status", ["approved", "pending", "under_review"])
// => "status:approved,pending,under_review"
search.not(): string
Exclude / negate: `-field:value`
search.not("status", "denied")
// => "-status:denied"
search.exists(): string
Field exists (is not null): `field:*`
search.exists("email")
// => "email:*"
search.notExists(): string
Field does not exist (is null): `-field:*`
search.notExists("deletedAt")
// => "-deletedAt:*"
search.contains(): string
Contains (case-insensitive): `field:*value*`
search.contains("name", "john")
// => "name:*john*"
search.startsWith(): string
Starts with (case-insensitive): `field:value*`
search.startsWith("name", "john")
// => "name:john*"
search.endsWith(): string
Ends with (case-insensitive): `field:*value`
search.endsWith("email", "@example.com")
// => "email:*@example.com"
search.quoted(): string
Quoted value (for values containing spaces): `field:"value with spaces"`
search.quoted("name", "john doe")
// => 'name:"john doe"'
search.text(): string
Full-text exact match (no field specified)
search.text("john")
// => "john"
search.textContains(): string
Full-text contains search (no field specified)
search.textContains("john")
// => "*john*"
search.textStartsWith(): string
Full-text starts with search (no field specified)
search.textStartsWith("john")
// => "john*"
search.textEndsWith(): string
Full-text ends with search (no field specified)
search.textEndsWith("smith")
// => "*smith"