---
title: "Advanced Search Plugin for Orangescrum Self-Hosted"
description: "Query work items in plain text: AND, OR, IN, IS EMPTY, ORDER BY, custom fields, and currentUser(). Save the query and share it. Self-hosted."
canonical: https://www.orangescrum.com/self-hosted/plugins/advanced-search
---

# Advanced Search Plugin for Orangescrum Self-Hosted

> For the complete documentation index, see [llms.txt](https://www.orangescrum.com/llms.txt).

1.  [Home](/)
2.  ›
3.  [Self-Hosted](/self-hosted)
4.  ›
5.  [Plugins](/self-hosted/plugins)
6.  ›
7.  Advanced Search

# Advanced Search

by [Orangescrum](/) · Productivity

Self-HostedVerifiedPower User

Advanced Search adds a small text query language over your work items. Write something like status = "In Progress" AND assignee = currentUser() ORDER BY due\_date ASC and get the matching tasks back. Queries run through the same company, project, and permission scoping as the normal task list, every value you type is bound as a parameter, and a query you use often can be saved, re-run, and shared.

Installs

Available

Active deployments

Support

Vendor Supported

Priority response

Trust

Self-Hosted

Your infra, your data

$499/year

Per company • Add-on to any Self-Hosted plan

[Buy & See All Plans](/self-hosted/pricing#addons)[Talk to Sales](/contact-sales)

-   AND, OR, NOT, and brackets for real boolean logic
-   IN, NOT IN, IS EMPTY, and a contains operator
-   ORDER BY one or several fields, ascending or descending
-   currentUser() so one query works for everyone
-   Custom fields queried by name or by identifier
-   Parse errors with the exact position and a caret
-   Saved queries you can re-run and share
-   Every value bound as a parameter, never concatenated

Pairs with [Self-Hosted Core ($1,500/yr) or Business ($2,250/yr)](/self-hosted/pricing)

[Overview](#overview)[Features](#features)[About](#about)[Install](#install)[FAQ](#faq)

## Screenshots

Advanced Search page with a query and its results

Parse error with the position and caret

Saved queries list, ready to re-run

## Key Features

### A Small, Readable Grammar

Field, operator, value, joined with AND, OR, and NOT, grouped with brackets, and sorted with ORDER BY. Short enough to learn in a sitting and precise enough to replace a stack of saved filters.

### Contains and Empty

The contains operator matches a substring in a title or description. IS EMPTY finds the unassigned work, the items with no labels, and the backlog with no sprint, which is usually what you were looking for.

### currentUser()

Write a query once with currentUser() in it and everyone who opens it sees their own work. One saved query instead of one per person.

### Sorting Inside the Query

ORDER BY takes one field or several, each ascending or descending, so the result arrives in the order you wanted rather than the order you have to click into.

### Custom Fields

Query your own fields by name or by identifier, with exact match, list membership, or substring. The fields you added to fit your process are searchable like any built-in one.

### Field Catalogue

An endpoint lists every queryable field, the operators it accepts, and an example, so the search page can teach the syntax instead of leaving people guessing.

### Aliases That Match How People Type

Common alternatives resolve to the canonical field, so assigned\_to, created\_by, milestone, points, and duedate all work without anyone having to memorise the one true spelling.

### Errors With a Caret

A bad query returns the message and the character position with a caret under the offending token. It never returns a server error and never leaks a fragment of the underlying query.

### Injection Safe by Construction

Every value you type is bound as a parameter and column names come only from the field registry, never from the text of the query. There is no path from the search box to the database.

### Scoped Like the Task List

Company, project membership, and the view-all-tasks permission apply to every query, so a clever filter cannot surface work the person could not already open.

### Saved Queries

Save a query with a name, list what you saved, re-run it, and delete it when it stops being useful. Saved queries sit alongside the filters you already have.

### Validate Before You Run

A parse-only endpoint checks a query without executing it, so the page can tell you the syntax is wrong before it goes anywhere near your data.

## About this plugin

### Why Advanced Search for Orangescrum?

Click-based filters run out of road quickly. As soon as you want work that is either high priority or overdue, but not closed, and not assigned to the person asking, you are fighting the interface. A text query expresses that in one line, and you can save it, paste it into a message, and hand it to someone else.

### Small on purpose

The grammar is deliberately compact: fields, comparison operators, a contains operator, list membership, an emptiness test, boolean joins, brackets, and sorting. That is enough to express most of what teams actually ask for, and small enough that the whole reference fits on one screen.

### Safe to put in front of everyone

Letting people type queries is only sensible if the engine is built for it. Every value is bound as a parameter and every column name comes from a fixed registry, so nothing typed into the box reaches the database as code. Invalid input returns a positioned parse error, not a server error and not a fragment of the query.

### It sees exactly what you already see

A query inherits the same scoping as the ordinary task list: your company, the projects you belong to, and the view-all-tasks permission. A more precise question does not become a way to see more. That is why it is safe to give the search page to everyone rather than to administrators only.

### Queries you keep

Save the query you keep retyping. Saved queries live alongside the existing saved filters, so there is one list of the searches your team relies on rather than two competing ones. Use currentUser() and one saved query serves the whole team.

### Where it stops

This is a query language over work items, not a general search engine. It does not search documents, wiki pages, comments, or files. It has no change-based operators, so you cannot ask which items moved from one status to another last week. Knowing the edges up front is more useful than discovering them halfway through a rollout.

### What's included

-   Advanced Search page mounted in the left navigation
-   Boolean operators AND, OR, and NOT with bracket grouping
-   Comparison operators for equal, not equal, greater, less, and their inclusive forms
-   A contains operator for substring matching on text fields
-   IN and NOT IN for list membership
-   IS EMPTY and IS NOT EMPTY for unassigned, unlabelled, and backlog work
-   ORDER BY with several fields, each ascending or descending
-   currentUser() resolving to the person running the query
-   Date literals and numeric comparisons
-   Queryable fields: title, description, key, status, custom status, type, priority, assignee, reporter, labels, sprint, project, story points, estimate, due date, and created date
-   Custom fields queried by name or by identifier
-   Field aliases that resolve to the canonical field
-   A field catalogue endpoint listing fields, operators, and examples
-   A validate endpoint that parses without executing
-   Parse errors carrying the message, the character position, and a caret
-   Saved queries with create, list, re-run, and delete, stored with the existing saved filters
-   Values bound as parameters and column names taken only from the field registry
-   Company, project membership, and view-all-tasks scoping applied to every query
-   Paginated results with a total count
-   Multi-tenant company-scoped data isolation

### Compatibility

Requires the Orangescrum Self-Hosted edition running PHP 8.2+, CakePHP 4.6+, and PostgreSQL 16. The plugin folder is QuerySearch and it is gated by the QUERY\_SEARCH\_ENABLED flag in config/constants.php. Saved queries reuse the core saved-filter table through a column the plugin migration adds, so no separate store is introduced. The search page is server rendered with plain JavaScript and needs no build step. Multi-tenant aware, so every query runs inside the caller's company and project scope.

## Installation

A self-hosted install takes a few minutes. Buy the add-on, drop the plugin into your `plugins/` directory, run the migrations, and you're live.

1.  1
    
    ### Buy the add-on
    
    Purchase the Advanced Search add-on from /self-hosted/pricing. Pricing for this add-on is being finalised, so confirm the current figure with sales before you budget.
    
2.  2
    
    ### Drop the plugin into your install
    
    Copy the QuerySearch/ folder into plugins/ on your self-hosted Orangescrum server.
    
3.  3
    
    ### Enable the feature flag and register the plugin
    
    Add \`define('QUERY\_SEARCH\_ENABLED', true);\` to config/constants.php and register \`QuerySearch\` in src/Application.php with routes enabled. The Advanced Search item then appears in the left navigation.
    
4.  4
    
    ### Run the database migration
    
    Run \`bin/cake migrations migrate --plugin QuerySearch\`. It adds the nullable query text column to the existing saved-filter table so saved queries reuse that store.
    
5.  5
    
    ### Open the page and read the field catalogue
    
    Open Advanced Search and review the list of fields, operators, and examples. It is the fastest way to hand the syntax to a team.
    
6.  6
    
    ### Save your first query
    
    Write a filter you retype often, use currentUser() where the answer should differ per person, and save it with a name so the whole team can run it.
    

## Frequently Asked Questions

### What can I query?

▾

Work items: tasks and the epic, feature, and story types. You can filter on title, description, the per-project item number, status, custom status, type, priority, assignee, reporter, labels, sprint, project, story points, estimated hours, due date, created date, and any custom field you have defined.

### Do people have to learn the syntax?

▾

Only if they want the power. The page lists every field with its operators and a worked example, so most queries are assembled by copying an example and changing a value. The existing click-based filters are untouched and still there for anyone who prefers them.

### Is it safe to let everyone type queries?

▾

Yes, and that was the design constraint. Every value you type is bound as a parameter, and column names come only from a fixed field registry rather than from the query text. A query also runs inside your existing company, project, and permission scope, so it cannot return work you could not already open.

### What is not supported?

▾

Several things, deliberately. There is no change-based search, so you cannot ask what moved from one status to another last week. You cannot nest one saved query inside another. There is no fuzzy or approximate matching. It searches work items only, not documents, wiki pages, comments, or attachments. And because the work item table has no modified timestamp, a query on the updated field falls back to the created date.

### Can I share a query with my team?

▾

Yes. Save it with a name and it is stored with the rest of your saved filters. A query written with currentUser() shows each person their own work, so one saved query covers a whole team rather than needing a copy per person.

### Does it replace the existing filters?

▾

No. It sits beside them. Saved queries and classic saved filters share the same store, so your team ends up with one list of the searches it relies on rather than two systems competing for the same job.
