Skip to main content

Pimcore Query Language (PQL)

Why was it created and how do I use it?

Matthew Dares  |  May 11, 2026  |  Reading Time: mins

The Pimcore Query Language (PQL) is an under-appreciated component of Pimcore’s releases of Platform Versions 2024 and 2025 (Pimcore 11 and Pimcore 12). Sitting between developers and the underlying OpenSearch engine, PQL provides a clean, declarative way to filter and retrieve indexed Data Objects, Assets, and Documents via the Generic Data Index (GDI).

However, most teams only scratch the surface, using PQL for simple equality or LIKE filters, without exploring relational queries, localized fields, empty/null logic, or query-string injection. This article expands on the official documentation by breaking down PQL’s operational model, it's advanced capabilities, and it's limitations, with practical examples pulled from real-world PIM and DAM implementations.

Where You'll Find PQL in Pimcore

Before diving into the details, it's worth noting that PQL doesn't live in one dedicated place; it's a query layer that surfaces wherever Pimcore filters elements from the Generic Data Index. The main area you'll encounter it is in Pimcore Studio's search and filter panels for Assets and Data Objects. Here is how to find it yourself:

  • Open either the Data Objects or Assets tree in Studio 
  • Click the search/filter icon at the top of the tree 
  • Switch the filter mode to Advanced (or PQL, depending on your Platform Version)
  • Type your query directly into the input 

This is the fastest way to experiment with PQL interactively.

Why PQL Exists: The Missing Abstraction Layer

Before diving into syntax, it’s worth understanding why PQL exists at all.

OpenSearch (or Elasticsearch) is a powerful search engine—but it knows nothing about Pimcore’s data models and how they relate to each other:

  • Data Object classes
  • Localized fields
  • Object bricks
  • Classification stores
  • Relation fields
  • Asset metadata
  • Workspace permissions

PQL acts as a translation layer:

  • Developers write simple PQL expressions
  • Pimcore resolves class definitions, relations, and field names
  • PQL is converted into OpenSearch JSON DSL
  • OpenSearch executes the query and returns hits

 

This means you get the power of OpenSearch without the complexity of hand-writing queries like:

{
  "bool": {
    "must": [
      { "term": { "standard_fields.color.keyword": "red" }},
      { "range": { "standard_fields.price": { "lt": 100 }}}
    ]
  }
}

Instead, you write:

color = "red" AND price < 100

Understanding the Field Model: The Key to Writing Good PQL

Most PQL difficulties come from not understanding how Pimcore maps data into the index. PQL operates across three main field categories:

1. System Fields (system_fields)

Automatically managed metadata:

  • id
  • type
  • creationDate
  • modificationDate
  • fullPath
  • published

2. Standard Files (standard_fields)

Flattened fields from class definitions or asset metadata – these are the fields on your data model and assets, including:

  • basic fields
  • localized fields
  • object-brick fields
  • relation fields
  • etc.

3. Custom Fields (custom_fields)

We won’t go into this in detail for this article, but custom_fields support user-defined additions or extensions to the index.  For more information: https://docs.pimcore.com/platform/Generic_Data_Index/Extending_Data_Index/Extend_Search_Index/

All of the examples we are using can be tried out on the Pimcore classic car demo. Contact us for details on getting access.

Field Name Resolution

PQL provides you with the ability to reference fields by short name:

productionYear = "1959"

But you can also fully qualify them:

standard_fields.productionYear = "1959"

Full qualification becomes critical in complex models where multiple fields share similar names across bricks, relations, or localized variants. Most people run into this in relations, where a field name like ‘description’ might be used on multiple objects. TORQ generally recommends fully qualifying common field names like this, especially for large, interrelated data models.

Relational Queries: The Most Powerful Part of PQL

This brings us to relational queries in PQL. This is where this utility truly adds value to the platform. Power users can quickly write plain-language style queries following the PQL syntax (stay tuned for this becoming fully plain language with AI-assisted transformation of queries).

PQL allows “join-like” filtering through relation fields using the syntax:

relationField:RelatedClass.field

Example 1 — Products by Manufacturer Name

manufacturer:Manufacturer.name = "Ford"

Example 2 — All Products Missing a Manufacturer

manufacturer = EMPTY

Under the hood, Pimcore resolves the relation, finds the related object in the GDI, extracts the required field, and generates the correct sub-query.

This is one of the biggest advantages PQL brings over raw OpenSearch—because OpenSearch itself has no concept of Pimcore relations. PQL lets us leverage knowledge of our data to further refine and filter results.

Example 3 — Filtering across relations with local conditions

manufacturer:Manufacturer.name = "Ford" AND (color = "red" OR productionYear <= 1970)

This query finds all cars made by Ford that are either red or built before 1970. The relation part resolves by first searching the Manufacturer index for Ford, then filtering cars linked to those results.

Example 4 — Asset relation with wildcard matching

gallery:Asset.fullPath LIKE "/Car Images/vw/*" AND series != EMPTY

This query finds all cars that have images stored under the VW asset folder and where the series field is not empty. The relation crosses into the Asset index to match file paths, while the second condition filters locally on the car object itself.

Localized Fields: Multi-Language Querying

In Pimcore, localized fields use the “.locale” suffix:

description.en LIKE "*small sports cars*"

description.fr LIKE "*petites voitures de sport*"

Example - Utilizing the Empty keyword to find missing translations

description.en != empty and description.de = EMPTY

This query is an example of strategically using the Empty keyword to find products that have untranslated descriptions, but looking for products with an English description but no German description.

Performance Considerations: How to Avoid Pain

Prefer equality over LIKE

Use *value sparingly

Minimize OR chains—replace with QUERY() where needed

Ensure your GDI mapping includes all searchable fields

Use field qualification in large, complex schemas

User Permissions in PQL Queries

PQL searches are automatically scoped to what each user is allowed to see without any extra configuration needed. When a user runs a PQL query, their workspace permissions are silently injected into the same OpenSearch query alongside their search conditions, meaning results are filtered at the database level before anything is returned. A user restricted to /Products/Europe/ querying color = "red" AND productionYear > 2020 will only ever see red post-2020 products inside their permitted folder. The query OpenSearch actually receives looks like:

{
  "bool": {
    "must": [
      { "term": { "standard_fields.color.keyword": "red" } },
      { "range": { "standard_fields.productionYear": { "gt": 2020 } } },
      { "prefix": { "system_fields.fullPath": "/Products/Europe/" } }
    ]
  }
}

The workspace restriction is just another filter clause, not a post-processing step, so it's fast, consistent, and impossible to circumvent through a clever query.

Where PQL Falls Short (and What to Use Instead)

PQL is excellent for structured filtering.
It is not:

  • A full-text relevance engine
  • A fuzzy search tool
  • A semantic search layer
  • A replacement for OpenSearch DSL
  • A scoring/boosting language

For advanced search, combine:

  • PQL filters
  • OpenSearch full-text queries
  • Pimcore’s headless search endpoints
  • AI/Agentic search (vector embeddings + RAG)

Conclusion: PQL as a Strategic Developer Tool

PQL is more than a convenience; it’s a core part of how Pimcore’s data layer exposes OpenSearch capabilities in a model-aware, power user and developer-friendly way. Once you understand how fields map into the index and how PQL resolves relations and localized fields, you can build incredibly powerful queries with a fraction of the code needed in raw DSL.

In modern PIM/DAM implementations, especially those involving thousands of SKUs, multilingual content, or complex asset relationships, PQL becomes indispensable.

If you're building product catalog APIs, enrichment workflows, data governance dashboards, or custom admin interfaces, mastering PQL will significantly improve performance, maintainability, and clarity of your search logic.

Advanced Topics

Advanced Searching with QUERY()

If you outgrow the PQL grammar, you can drop into raw OpenSearch Query String syntax:

QUERY("standard_fields.color:(red OR black)")

Where you can find objects with the colors red or black.

Or fuzzy matching:

QUERY("standard_fields.color:wte~2")

Where you can search for wte with a parameter of 2, which will allow you to match on values that are 2 characters off.

Or boosting:

QUERY("standard_fields.color:(whte~1 AND red)")

Where colors need to be white and red, but white can be off by 1 character.

This is where PQL becomes a hybrid language—simple for most use cases, but capable of exposing the full power of OpenSearch when needed.

Note:
You must use fully-qualified field names inside QUERY().

Date Math: Temporal Queries for Catalogs

Because PQL forwards date fields directly to OpenSearch, you can use date math:

 Examples

modificationDate <= 'now'

modificationDate <= 'now-1d/d'

You see all objects minus the ones that were modified today

If this article has you interested, curious, or left with questions, feel free to reach out to our team for a full walk-through! 

https://builtbytorq.com/contact

 

Other Posts

Case Studies

Ready to get started?

Talk to an expert