Modern Text Search in AL

With BC25, there’s a new way of filtering (searching) for text in Business Central and also in AL. In this video, I take the new feature for a spin. Check it out:

https://youtu.be/oXnyEFY8c3U

With Business Central 2025 Wave 1 (version 25), Microsoft introduced a powerful new feature: Modern Text Search. This is a full-stack enhancement that benefits both end users through the UI and AL developers through new field properties and filter syntax. In this video, Erik demonstrates how modern search works, compares it to legacy search, shows the underlying AL code, and runs some informal performance tests to see if the “faster” label holds up.

A Full-Stack Feature: UI and AL Combined

What makes this feature particularly interesting is that it spans the entire stack. End users get a new option in the search bar — a dropdown with two choices:

  • Use modern search (faster) — the new approach
  • Use legacy search — the traditional behavior

But it’s not just a UI toggle. The behavior is controlled by AL properties on table fields, meaning developers have direct control over which fields participate in modern text search.

Legacy Search vs. Modern Search: A Quick Comparison

Erik demonstrates the difference using a database populated with 53,000 customer names (generated using an AI web service for random demo data). Searching for “Erik” reveals clear differences:

Legacy Search

Searching for “Erik” with legacy search returns 100 results. This includes true “Eriks” but also names like “Frederick” — because the text “erik” appears as a substring within the name. Legacy search essentially performs a case-insensitive wildcard match (@*erik*).

Modern Search

Switching to modern search, the same query returns only 43 results. These are predominantly names where “Erik” appears as an actual word (or the start of a word), like “Erik,” “Erika,” etc. The modern search is smarter about word boundaries.

Multi-Word Search

The most impressive difference is multi-word search. With modern search enabled, you can search for “Hoffman Erik” and it will find “Erik Hoffman” — even though the words are in reverse order. You can even abbreviate: “Hof Erik” works too. This cross-column, order-independent word matching is something legacy search simply cannot do.

The AL Property: OptimizeForTextSearch

Under the hood, this feature is controlled by a new field property in AL: OptimizeForTextSearch. Looking at the Customer table in the base application, you can see which fields have this enabled:

  • No. — OptimizeForTextSearch = true
  • Name — OptimizeForTextSearch = true
  • Name 2 — OptimizeForTextSearch = true
  • Address — OptimizeForTextSearch = true
  • Address 2 — OptimizeForTextSearch = true
  • City — OptimizeForTextSearch = true
  • Contact — OptimizeForTextSearch = true
  • Phone No. — OptimizeForTextSearch = true
  • Telex No. — OptimizeForTextSearch = true
  • Search Name — does not have it (which makes sense)

Erik shares an amusing aside here: the Telex field and even the Telex Answer Back field are included in the optimization. For those unfamiliar, Telex was a predecessor to the fax machine — essentially connected typewriters used in commercial trading and shipping back in the 1970s and 80s. Erik recalls encountering it in the 1990s at a shipping customer who still used it to communicate with the Far East. While it’s safe to say nobody has sent a Telex in the last 20 years, the field persists in Business Central — and now it’s being optimized for modern text search. As Erik puts it: “Maintaining an index for this to work is just hilarious. Good one, Microsoft.”

Filter Syntax: @ vs. &&

In AL code, the difference between legacy and modern search comes down to filter syntax:

  • @erik* — Legacy-style: case-insensitive wildcard search (the @ prefix makes it case-insensitive)
  • &&Erik* — Modern search: the && prefix activates the new text search engine

The && prefix tells Business Central to use the modern text search infrastructure. With this syntax, the search operates on word boundaries and supports the order-independent multi-word matching demonstrated in the UI.

Performance Testing: Is It Actually Faster?

The modern search option in the UI proudly declares itself “faster.” Erik puts this to the test with a simple but honest benchmarking approach — timing filter operations in AL code:

pageextension 50100 CustomerListExt extends "Customer List"
{
    trigger OnOpenPage()
    var
        starttime: DateTime;
    begin
        starttime := CurrentDateTime();
        Rec.Setfilter(Name, '@erik*'); // Legacy search
        //Rec.Setfilter(Name, '&&Erik*'); // Modern search

        if Rec.FindSet() then
            repeat
            until Rec.Next() = 0;

        message('Time spent %1', CurrentDateTime() - starttime);
    end;
}

Erik acknowledges this isn’t rigorous performance testing — the dataset is small (only ~40 matching records), caching effects come into play, and FindSet behavior with small result sets doesn’t fully stress the system. But the results are still telling:

Results

Search Type Filter Syntax Typical Time
Legacy search @erik* 27–58 ms (averaging ~35-40 ms)
Modern search &&Erik* 13–17 ms

After running multiple iterations to warm up caches and get stable numbers, the verdict from Erik’s “very scientific performance testing department” is clear: modern search is roughly twice as fast for this scenario. Not quite three times, but consistently and significantly faster.

Practical Benefits: Item Search on Documents

Beyond list pages and the global search bar, modern text search dramatically improves the experience on document lines. Erik demonstrates this on a Sales Order:

  • Typing “chair blue” finds items with both words in the description
  • Typing “blue chair” finds the same items — word order doesn’t matter
  • Typing “swivel yellow” works just as intuitively
  • Typing “green chair” narrows results appropriately

This is a huge quality-of-life improvement for end users. When you’re entering lines on a sales order, you’re not thinking about programming filters — you’re just typing words to find stuff. Modern search makes that natural.

Real-World Application: Custom Search Implementations

Erik shares that he previously built a custom multi-word search feature from scratch for one of his apps (Advanced Portal Designer, used for eFocus customer portals). That implementation involved creating a dedicated search table with an indexed field, splitting search terms into individual words, filtering the search table for each word, building a temporary results table, and ranking results by hit count — records matching more search words appearing higher in results.

With the introduction of OptimizeForTextSearch and the && filter syntax, much of that custom infrastructure may no longer be necessary. The platform now provides this capability natively.

Key Takeaways

  • Enable it on your fields: Set OptimizeForTextSearch = true on text fields that users commonly search against
  • Use the && prefix in code: When you want modern search behavior in AL filters, use the && prefix instead of @
  • It’s genuinely faster: Even informal testing shows roughly 2x performance improvement
  • Multi-word, order-independent search: The killer feature — users can type words in any order and find matching records
  • Full-stack feature: Benefits both end users (through the UI toggle) and developers (through AL properties and filter syntax)
  • Requires BC25+: The app.json shows "application": "25.0.0.0" and "runtime": "14.0", confirming this is a 2025 Wave 1 feature

Modern text search is one of those features that improves the daily experience for every user while giving developers a powerful new tool. If you’re building extensions with searchable fields, make sure to evaluate which fields should have OptimizeForTextSearch enabled — your users will notice the difference.