| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 2 个月前 | ||
| 9 天前 | ||
| 1 个月前 | ||
| 2 个月前 | ||
| 19 天前 | ||
| 1 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 1 个月前 |
@react-querybuilder/expr
Augments react-querybuilder with arithmetic and function expression support, letting either side of a rule be a computed operand built from fields, literals, and functions—e.g. (price * quantity) > 100 or ABS(discount) >= 5.
To see this in action, check out the react-querybuilder demo with the "expressions" option enabled.
Installation
npm i react-querybuilder @react-querybuilder/expr
# OR yarn add / pnpm add / bun add
Usage
All React exports live in the /ui entry point (@react-querybuilder/expr/ui); the root entry is framework-agnostic, exporting only rule processors, the validator, the function-metadata and serializer helpers, and types (so it can run server-side).
Components
Wrap your QueryBuilder in the QueryBuilderExpressions context provider. It overrides the field selector, value-source selector, and value editor to host expressions. Rules without expressions render exactly as before.
import { QueryBuilder } from 'react-querybuilder';
import { QueryBuilderExpressions } from '@react-querybuilder/expr/ui';
const App = () => (
<QueryBuilderExpressions allowFunctionsOnLHS>
<QueryBuilder fields={fields} query={query} onQueryChange={setQuery} />
</QueryBuilderExpressions>
);
- Right-hand side — add
"expression"to a field'svalueSourcesto offer it in that rule's value-source selector. The expression is stored inrule.value(withvalueSource: "expression"). - Left-hand side — set
allowFunctionsOnLHSto wrap the rule'sfieldin a unary function, stored onrule.lhs.
Pass custom function metadata (UI label + arity) via the functions prop; it is merged over the built-in defaultFunctionMeta (arithmetic + - * /, plus min, max, mod, abs, upper, and lower). Serialization for each export format is registered separately on the export processors.
Export
formatQuery needs an expression-aware rule processor to serialize the lhs/rhs nodes. The package provides a ready-to-use processor (and a getExpressionRuleProcessor* factory) for every export format that can represent computed operands:
import { formatQuery } from 'react-querybuilder';
import { expressionRuleProcessorSQL } from '@react-querybuilder/expr';
formatQuery(query, { format: 'sql', ruleProcessor: expressionRuleProcessorSQL });
Supported formats
formatQuery format |
Ready-to-use processor | Factory | Extra context required |
|---|---|---|---|
sql |
expressionRuleProcessorSQL |
getExpressionRuleProcessorSQL |
— |
parameterized/_named |
expressionRuleProcessorParameterized |
getExpressionRuleProcessorParameterized |
— |
jsonlogic |
expressionRuleProcessorJsonLogic |
getExpressionRuleProcessorJsonLogic |
— (register operators before applying, see below) |
cel |
expressionRuleProcessorCEL |
getExpressionRuleProcessorCEL |
— |
spel |
expressionRuleProcessorSpEL |
getExpressionRuleProcessorSpEL |
— |
cypher/gql |
expressionRuleProcessorCypher |
getExpressionRuleProcessorCypher |
— |
sparql |
expressionRuleProcessorSPARQL |
getExpressionRuleProcessorSPARQL |
— |
jsonata |
expressionRuleProcessorJSONata |
getExpressionRuleProcessorJSONata |
— |
mongodb_query |
expressionRuleProcessorMongoDBQuery |
getExpressionRuleProcessorMongoDBQuery |
— |
mongodb (deprecated) |
expressionRuleProcessorMongoDB |
getExpressionRuleProcessorMongoDB |
— |
elasticsearch |
expressionRuleProcessorElasticSearch |
getExpressionRuleProcessorElasticSearch |
— |
natural_language |
expressionRuleProcessorNL |
getExpressionRuleProcessorNL |
— |
drizzle |
expressionRuleProcessorDrizzle |
getExpressionRuleProcessorDrizzle |
columns, drizzleOperators |
sequelize |
expressionRuleProcessorSequelize |
getExpressionRuleProcessorSequelize |
sequelizeOperators, sequelizeWhere, sequelizeLiteral, sequelizeCol |
tanstack_db |
expressionRuleProcessorTanStackDB |
getExpressionRuleProcessorTanStackDB |
tanStackDbOperators, _tanstackDbRefs, _tanstackDbPrimaryRef |
Expression rules support scalar comparisons (=, !=, <, <=, >, >=), null/notNull, and between/notBetween (with expression bounds). Rules without expressions, with an unsupported operator, or missing required context, fall back to the stock processor for that format.
Note: string-match operators (
contains,beginsWith,endsWith, and their negations) support expression operands—an expression RHS (search term) and/or LHS—for every export format excepttanstack_db, each using that dialect's native construct. Thetanstack_dbformat omits such rules (itslikeneeds a static pattern), andsequelizeomits a string-match rule whose search term is a bare field reference (valueSource: 'field').
The library-backed formats need the same context helpers their stock processors need. For example, drizzle:
import { getOperators } from 'drizzle-orm';
import { expressionRuleProcessorDrizzle } from '@react-querybuilder/expr';
const where = formatQuery(query, {
format: 'drizzle',
preset: 'sqlite', // resolves min/max to MIN/MAX (else LEAST/GREATEST)
ruleProcessor: expressionRuleProcessorDrizzle,
context: { columns, drizzleOperators: getOperators() },
});
and sequelize:
import { col, literal, Op, where } from 'sequelize';
import { expressionRuleProcessorSequelize } from '@react-querybuilder/expr';
const whereClause = formatQuery(query, {
format: 'sequelize',
preset: 'sqlite',
ruleProcessor: expressionRuleProcessorSequelize,
context: {
sequelizeOperators: Op,
sequelizeWhere: where,
sequelizeLiteral: literal,
sequelizeCol: col,
},
});
Custom functions
When using custom functions, pass matching serializers to each format's processor factory (a function present in the UI but missing a serializer for the export format is omitted from that format's output):
import { getExpressionRuleProcessorSQL } from '@react-querybuilder/expr';
const sqlProcessor = getExpressionRuleProcessorSQL({
pow: (_opts, base, exp) => `POWER(${base}, ${exp})`,
});
formatQuery(query, { format: 'sql', ruleProcessor: sqlProcessor });
Each getExpressionRuleProcessor* factory takes a single serializer registry merged over that format's built-ins.
Applying JsonLogic output
Before applying the jsonlogic output, register the operators the expressions emit. JsonLogic ships + - * / %, min, and max as built-ins, but others like abs, upper, and lower are not. Add them to your JsonLogic instance like so:
import { add_operation, apply } from 'json-logic-js';
import { jsonLogicExpressionOperators } from '@react-querybuilder/expr';
for (const [op, func] of Object.entries(jsonLogicExpressionOperators)) {
add_operation(op, func);
}
const logic = formatQuery(query, {
format: 'jsonlogic',
ruleProcessor: expressionRuleProcessorJsonLogic,
});
apply(logic, data);
Validation
createExpressionValidator returns a QueryValidator that flags rules with invalid expressions (unknown function, arity mismatch, empty field reference). Use it as formatQuery's validator option or as a <QueryBuilder validator> prop:
import { createExpressionValidator } from '@react-querybuilder/expr';
const validator = createExpressionValidator(functions);