# ExecuteAdvancedSearch - Advanced Documentation ## When to Use **This executes an ad-hoc advanced search** - use it when you are assembling a search dynamically (SearchType, Columns, Filters) instead of referencing a saved search by ID. If a saved search already exists and needs no filter changes beyond its parameters, use `GetAdvancedSearchResults` or `GetAdvancedSearchResultString` instead - they are cheaper and reuse a stored definition. **The normal use case: a saved search is almost right, but a filter value you need to change is not parameterized** - a date range, a staff ID, a value range the search's author never exposed as a parameter. Fetch the tree with `GetAdvancedSearchFilters`, change that one value in place, and execute the modified definition here. Nothing is saved - the definition is executed and discarded. ## The Escalation Ladder Reach for the cheapest rung that satisfies the request: 1. **Saved search as-is** - `GetAdvancedSearchResults` with no parameters. 2. **Parameterized filter** - `GetAdvancedSearchResults` with `ParametersJson`; replace the populated value slot of the filter found by `ParameterName`. 3. **Non-parameterized filter needs a different value** - fetch the tree with `GetAdvancedSearchFilters`, change the value in place, execute here. 4. **No suitable search exists** - assemble Columns and Filters from scratch and execute here. Last resort. Rungs 2, 3, and 4 are the same skill: the fetched definition is always the template, and the populated value slot is always the worked example. What varies is how much of it you change. **The round trip is a supported contract.** The output of `GetAdvancedSearchColumns` and `GetAdvancedSearchFilters` feeds into this endpoint unchanged - fetch from a sample search, modify, execute. **Building from scratch (rung 4):** use `GetAdvancedSearchFields` as the catalog of available fields, and the columns and filters of existing searches as worked examples of valid field chains. A `FieldList` is an ordered chain: every entry except the last carries `NextEntityName`, and the last entry - the leaf - carries the `DataType` and must not have a `NextEntityName`. Note that ad-hoc definitions are not validated field-by-field before execution: a malformed chain surfaces as a query build or execution error, not a friendly validation message. Copy working chains rather than inventing them. **Companion calling conventions** (positional args): - `GetAdvancedSearchColumns(advancedSearchId)` -> `SearchColumnInfo[]` - `DisplayName` plus `FieldList`, whose last entry (the leaf) carries `DataType` - `GetAdvancedSearchFilters(advancedSearchId)` -> a `FilterGroupInfo` tree - each filter carries `ParameterName`, `Operator`, and its value slots - `GetAdvancedSearchFields(fieldType, isColumnField)` -> `SearchField[]` - the field catalog NEVER call GetEndpointDetail for these three when assembling an ad-hoc search - everything the workflow needs from them is shown above. **Caching:** the result is identical in shape to `GetAdvancedSearchResults`, so all of its caching and aggregation guidance applies here unchanged - cache the packed `DataJson` before computing, return the batchId early, batch every question into the one run. See `GetAdvancedSearchResults` documentation. ## Overview Executes a caller-supplied advanced search against `Claim`, `Contact`, or `Person` data with no saved search record. Applies the same SQL construction, 30 second execution timeout, row-level claim security, time zone handling, and firm/company membership checks as the saved-search endpoints - the only difference is that Columns and Filters come directly from the request instead of being loaded from a saved `AdvancedSearchID`. ## Parameters - **SearchType** - `"Claim"`, `"Contact"`, or `"Person"`. Determines which base view the search runs against. Sent and received as a string on the wire. - **Columns** - list of `SearchColumnInfo` describing the fields to return, in the same shape returned by `GetAdvancedSearchColumns`. - **Filters** - a `FilterGroupInfo` filter tree, in the same shape returned by `GetAdvancedSearchFilters`. - **PersonID** - ID of the person executing the search (used for security filtering and time zone conversion). Pass the current user's ID. ## Return Structure Returns an `AdvancedSearchResults` object, identical in shape to `GetAdvancedSearchResults`: - **Columns** - field names, types, and display names for each column in the result set - **DataJson** - list of JSON-serialized `row.ItemArray` values (one entry per row) ## Script Example ```javascript async () => { const columns = [ { DisplayName: "Claim Name", FieldList: [{ FieldName: "Name", FieldSource: "Claim", FieldType: "Entity", DataType: "TextShort", ID: 13917 }] } ]; const filters = { Condition: "and", Children: [ { Condition: "and", FieldList: [{ FieldName: "Status", FieldSource: "Claim", FieldType: "Entity", DataType: "Dropdown", ID: 13920, Operator: "Exactly Matches", ValueString: "Open" }] } ] }; const results = await SecureApi.ExecuteAdvancedSearch("Claim", columns, filters, 8514); const colNames = results.Columns.map(c => c.DisplayName); const rows = results.DataJson.map(json => { const vals = JSON.parse(json); const row = {}; colNames.forEach((name, i) => row[name] = vals[i]); return row; }); return { total: rows.length, rows }; } ```