{"id":45175,"date":"2026-06-20T18:32:18","date_gmt":"2026-06-20T16:32:18","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/?p=45175"},"modified":"2026-06-20T18:32:20","modified_gmt":"2026-06-20T16:32:20","slug":"m-files-bd-queries-objecttype-class-filters-date-tokens","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/m-files-bd-queries-objecttype-class-filters-date-tokens\/","title":{"rendered":"M-Files BD &#8211; Queries: objectType, class, filters, date tokens"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">In the previous posts of this series, I covered the <a href=\"https:\/\/www.dbi-services.com\/blog\/m-files-bd-anatomy-of-a-dashboard-definition\/\" target=\"_blank\" rel=\"noreferrer noopener\">anatomy of a dashboard definition<\/a> and the seven widget types (<a href=\"https:\/\/www.dbi-services.com\/blog\/m-files-bd-scalar-widgets-kpinumber-and-gauge\/\" target=\"_blank\" rel=\"noreferrer noopener\">KPI &amp; gauge<\/a>, <a href=\"https:\/\/www.dbi-services.com\/blog\/m-files-bd-trend-widgets-line-and-area\/\" target=\"_blank\" rel=\"noreferrer noopener\">line &amp; area<\/a>, <a href=\"https:\/\/www.dbi-services.com\/blog\/m-files-bd-distribution-and-tabular-widgets-donut-bar-table\/\" target=\"_blank\" rel=\"noreferrer noopener\">donut, bar &amp; table<\/a>) the engine supports, as of now. In this one, we will go through the Business Dashboard queries, i.e. the <strong><em>query<\/em><\/strong> section that I pretty much ignores so far. It is now time to look at it a bit more.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A query has four parts: <strong><em>objectType<\/em><\/strong>, <strong><em>class<\/em><\/strong>, <strong><em>filters<\/em><\/strong>, and <strong><em>aggregation<\/em><\/strong>. This post covers the first three. The fourth (aggregations, including its reducers) is the topic of the next post.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As mentioned before, the principle that drove the design of the Business Dashboard is to <strong>be generic<\/strong>. The engine never enumerates specific business values, it only translates the structured JSON query into a standard M-Files server search.<\/p>\n\n\n\n<h2 id=\"h-1-objecttype-the-m-files-object-type-to-query\" class=\"wp-block-heading\">1. objectType &#8211; the M-Files object type to query<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Every query starts with <strong><em>objectType<\/em><\/strong>. It is the M-Files object type the engine searches against, addressed by its display name (the singular form is fine, the engine resolves it and uses it).<\/p>\n\n\n\n<h3 id=\"h-1-1-single-object-type\" class=\"wp-block-heading\">1.1. Single object type<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The simplest form is a string:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n&quot;objectType&quot;: &quot;Document&quot;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Or any other object type defined in your vault:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n\/\/ Looking for Customers\n&quot;objectType&quot;: &quot;Customer&quot;\n\n\/\/ Looking for Projects\n&quot;objectType&quot;: &quot;Project&quot;\n\n\/\/ Looking for Employees\n&quot;objectType&quot;: &quot;Employee&quot;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The display name is <strong>case-insensitive<\/strong> but must otherwise match what the vault shows. Please note that, if the vault is let&#8217;s say, in German, you might need to use &#8220;Dokument&#8221; and not &#8220;Document&#8221;. In short, you need to use what the vault defines\/shows.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the name does not match, the widget shows a clear <strong><em>\u2717 Object type &#8216;xxx&#8217; not found in this vault<\/em><\/strong> error.<\/p>\n\n\n\n<h3 id=\"h-1-2-multiple-object-types\" class=\"wp-block-heading\">1.2. Multiple object types<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When the same logical entity exists across more than one M-Files object type (for example, a &#8220;Proposal&#8221; can be both a Document and a Document collection), you can pass an array:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n&quot;objectType&quot;: &#x5B;&quot;Document&quot;, &quot;Document collection&quot;]\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The engine resolves every name and builds a single search to find all matching objects. This behaves like the <strong><em>&#8220;is one of&#8221;<\/em><\/strong> filter in M-Files Advanced Search. Please note that the Drill-through will also inherit the same scope, automatically.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A small but important detail: even in this case, the engine executes a single search. This matters for performance and for consistency (a single <strong><em>serverScanMaxResults<\/em><\/strong> cap applies, not two independent caps).<\/p>\n\n\n\n<h2 id=\"h-2-class-narrowing-the-scope-and-the-perf-impact\" class=\"wp-block-heading\">2. class &#8211; narrowing the scope (and the perf impact)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong><em>class<\/em><\/strong> field is optional but <strong><em>strongly<\/em><\/strong> recommended. It restricts the query to one specific class:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n&quot;objectType&quot;: &quot;Document&quot;,\n&quot;class&quot;: &quot;Contract or Agreement&quot;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Querying &#8220;all Documents&#8221; in a vault that contains 50&#8217;000 documents of which only 1&#8217;000 are Contracts is pure waste. Adding <strong><em>&#8220;class&#8221;: &#8220;Contract or Agreement&#8221;<\/em><\/strong> narrows the scan immediately, which both improves performance and makes the widget result more meaningful.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore, both M-Files Administrators and M-Files Users will thank you for selecting the right class to use. It avoids slowness, irrelevant results and reduces resource usage. You should always set a <strong><em>class<\/em><\/strong>, when possible.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When <strong><em>objectType<\/em><\/strong> is an array and <strong><em>class<\/em><\/strong> is specified, the engine will find any object, from that class, from any of the object types listed. So the following will match Proposal-class objects from both types:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n&quot;objectType&quot;: &#x5B;&quot;Document&quot;, &quot;Document collection&quot;],\n&quot;class&quot;: &quot;Proposal&quot;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">If the class is misspelled, the widget shows a <strong><em>\u2717 Class &#8216;xxx&#8217; not found on the specified object type(s)<\/em><\/strong> error. As with object types, the name depends on what the vault defines\/shows.<\/p>\n\n\n\n<h2 id=\"h-3-filters-the-and-combined-conditions\" class=\"wp-block-heading\">3. filters &#8211; the AND-combined conditions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong><em>filters<\/em><\/strong> array, which is optional, contains zero or more conditions. If you specify multiple filters, then <strong>all filters must match<\/strong>. That means that M-Files applies a AND semantic between each filter. By the way, M-Files doesn&#8217;t directly support &#8220;OR&#8221; conditions, it always joins them. The only &#8220;kind-of-an-exception&#8221;, as far as I know, is the <strong><em>&#8220;is one of&#8221;<\/em><\/strong> where you can set multiple values from the Lookup\/MultiSelectLookup property values. But that&#8217;s only a single condition, not multiple conditions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here is an example of a filter:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n&quot;filters&quot;: &#x5B;\n  { &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;greaterOrEqual&quot;,\n    &quot;value&quot;: &quot;@today&quot;, &quot;valueType&quot;: &quot;dateToken&quot; },\n  { &quot;property&quot;: &quot;Agreement type&quot;, &quot;operator&quot;: &quot;equals&quot;,\n    &quot;value&quot;: &quot;Subcontracting Agreement&quot; }\n]\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Each filter has up to four fields:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><em>property<\/em><\/strong>: the property display name on which to apply the operator \/ value.<\/li>\n\n\n\n<li><strong><em>operator<\/em><\/strong>: one of the operators listed in section 4 below.<\/li>\n\n\n\n<li><strong><em>value<\/em><\/strong>: the value to use for the comparison with the property&#8217;s actual value. For the four &#8220;presence&#8221; operators (<strong><em>isEmpty<\/em><\/strong>, <strong><em>isNotEmpty<\/em><\/strong>, <strong><em>isPresentEmpty<\/em><\/strong>, <strong><em>isPresentNotEmpty<\/em><\/strong>), this parameter should NOT be defined. For the &#8220;begin-end&#8221; operators (<strong><em>between<\/em><\/strong> \/ <strong><em>notBetween<\/em><\/strong>, this parameter should be an array of two elements. For the &#8220;is one of&#8221; operators (<strong><em>inList<\/em><\/strong> \/ <strong><em>notInList<\/em><\/strong>), this parameter should be an array of at least two elements. Finally, in all other cases, it&#8217;s simply a string.<\/li>\n\n\n\n<li><strong><em>valueType<\/em><\/strong>: either <strong><em>&#8220;literal&#8221;<\/em><\/strong> (default, it means to use the value as-is) or a <strong><em>&#8220;dateToken&#8221;<\/em><\/strong> (covered in section 5).<\/li>\n<\/ul>\n\n\n\n<h2 id=\"h-4-the-filter-operators\" class=\"wp-block-heading\">4. The filter operators<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The engine supports a rich set of operators across two execution paths:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Native<\/strong>: runs server-side before the <strong><em>serverScanMaxResults<\/em><\/strong> cap is applied. Therefore, this is the preferred option, when possible.<\/li>\n\n\n\n<li><strong>Post-filter<\/strong>: runs in memory after the server returns up to <strong><em>serverScanMaxResults<\/em><\/strong> objects. Therefore, this is correct and useful when you want to do something that M-Files doesn&#8217;t support out-of-the-box but that still makes sense for your Business use-case.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">In short, whenever possible, prefer to apply a <strong><em>native<\/em><\/strong> filter. The main reason for this is simple. Let&#8217;s assume that you have 1&#8217;000 Contracts in the vault:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>If you apply a <strong><em>native<\/em><\/strong> filter, for example <strong><em>Effective through &gt;= @today<\/em><\/strong>, then if only 200 of them match that criteria, then M-Files will only return these 200 objects directly. There is no loss of performance here.<\/li>\n\n\n\n<li>If you apply a <strong><em>post-filter<\/em><\/strong>, for example <strong><em>Effective through contains 2026-12<\/em><\/strong>, then M-Files will have no other choice than returning all 1&#8217;000 Contracts first. On top of that, the post-filter compares the value of Effective through and checks whether it contains &#8220;2026-12&#8221;. This is because the &#8220;contains&#8221; condition doesn&#8217;t exist in M-Files for Date properties. Therefore, we cannot use what doesn&#8217;t exist, but we still want to provide that possibility \/ logic, and therefore it is done in memory after returning all results. In that example, you get 5x more results and on top of it, you also need to check which ones match the expected value.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The performance difference between <strong><em>native<\/em><\/strong> and <strong><em>post-filter<\/em><\/strong> is imperceptible for small result sets (&lt;few hundreds), but you would probably feel it if you expect to fetch thousands of results. A great catch, if you need to apply a post-filter for a valid business reasons, is to first apply a native one, which highly reduces the result set, and then apply the post-filter one that you need. Also, don&#8217;t forget to specify a <strong><em>class<\/em><\/strong>!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then, let&#8217;s proceed with a deep-dive on the different operators (if you only want the &#8220;summary&#8221;, look at the end of section 4 for the cheat sheet). The 22 operators support all data types, without exceptions, contrary to M-Files operators which offer much less capabilities. The only distinction is, as mentioned above, whether the operator is native or post-filter.<\/p>\n\n\n\n<h3 id=\"h-4-1-equals-and-notequal\" class=\"wp-block-heading\">4.1. equals and notEqual<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">As you would expect, these are for exact match. Only the MultiLineText properties are processed as post-filter.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Agreement type&quot;, &quot;operator&quot;: &quot;equals&quot;,\n  &quot;value&quot;: &quot;Subcontracting Agreement&quot; }\n\n{ &quot;property&quot;: &quot;Customer&quot;, &quot;operator&quot;: &quot;notEqual&quot;,\n  &quot;value&quot;: &quot;ESTT Corporation (IT)&quot; }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">When using display names on Lookup properties (Lookup or MultiSelectLookup), as its the case in above example, the value lists are cached, so that each execution doesn&#8217;t need to re-fetch the things that it already knows of, and it can just use it directly, to ask M-Files what&#8217;s the updated count.<\/p>\n\n\n\n<h3 id=\"h-4-2-lessthan-greaterthan-lessorequal-greaterorequal\" class=\"wp-block-heading\">4.2. lessThan, greaterThan, lessOrEqual, greaterOrEqual<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">These &#8220;range&#8221; operators support all property types except Boolean, because it doesn&#8217;t make any sense to apply a &#8220;lessThan&#8221; to a Boolean&#8230; In addition, and similarly to above, only the MultiLineText properties are processed as post-filter, everything else is native. Obviously, you can apply these operators on Date and Numeric values, but it also works with Text, Lookup or MultiSelectLookup. When it needs to work on Text-based properties, it does a lexicographic comparison (e.g. ABC &lt; ABD, ACE &gt; ABB).<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Due date&quot;, &quot;operator&quot;: &quot;lessThan&quot;,\n  &quot;value&quot;: &quot;@today&quot;, &quot;valueType&quot;: &quot;dateToken&quot; }\n\n{ &quot;property&quot;: &quot;Amount&quot;, &quot;operator&quot;: &quot;greaterOrEqual&quot;, &quot;value&quot;: 1000 }\n<\/pre><\/div>\n\n\n<h3 id=\"h-4-3-between-and-notbetween\" class=\"wp-block-heading\">4.3. between and notBetween<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">These as also &#8220;range&#8221; operators but I put them separately because the <strong><em>value<\/em><\/strong> must be a two-element array, as previously written. <strong><em>between<\/em><\/strong> is, otherwise, exactly the same as lessThan\/greaterThan\/lessOrEqual\/greaterOrEqual. In the array, you would provide the begin and the end of the range. to fetch.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;between&quot;,\n  &quot;value&quot;: &#x5B;&quot;@startOfYear&quot;, &quot;@endOfYear&quot;], &quot;valueType&quot;: &quot;dateToken&quot; }\n\n{ &quot;property&quot;: &quot;Amount&quot;, &quot;operator&quot;: &quot;between&quot;, &quot;value&quot;: &#x5B;100, 1000] }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong><em>notBetween<\/em><\/strong> is the opposite of <strong><em>between<\/em><\/strong>, obviously, but it&#8217;s a bit more than that&#8230; As previously mentioned, M-Files does NOT handle <strong><em>OR<\/em><\/strong> logic. But if you think about it, a &#8220;notBetween&#8221; is actually an OR, because you want values below the range OR above the range (<strong><em>value &lt; low OR value &gt; high<\/em><\/strong>). Because of that, <strong><em>notBetween<\/em><\/strong> is always a <strong>post-filter<\/strong>, without exception.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Amount&quot;, &quot;operator&quot;: &quot;notBetween&quot;, &quot;value&quot;: &#x5B;100, 1000] }\n<\/pre><\/div>\n\n\n<h3 id=\"h-4-4-isempty-isnotempty-ispresentempty-ispresentnotempty\" class=\"wp-block-heading\">4.4. isEmpty, isNotEmpty, isPresentEmpty, isPresentNotEmpty<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">These four operators test whether a property has a value, as the name suggests&#8230; However, there is a catch: M-Files only distinguish between &#8220;the property is present and empty&#8221; or &#8220;the property is present and non-empty&#8221;.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You might have faced that with Templates for example. That&#8217;s a pretty common occurrence. In M-Files, there is a parameter &#8220;Is template&#8221; which indicates whether a specific object has been defined as a template. But that parameter is only present in a few select objects, it&#8217;s usualy not present on all of them. Therefore, if you search for &#8220;Is template &#8211; is empty&#8221;, you will most probably find 0 results, because M-Files only check for documents where the property is present and where it is empty.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The distinction is simple but it matters a lot. That&#8217;s why in the Business Dashboard, the <strong><em>native<\/em><\/strong> M-Files &#8220;is empty&#8221; \/ &#8220;is not empty&#8221; have been renamed as <strong><em>isPresentEmpty<\/em><\/strong> and <strong><em>isPresentNotEmpty<\/em><\/strong>. These are the fully native option from M-Files, and therefore they run on the server-side.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;isPresentEmpty&quot; }\n\n{ &quot;property&quot;: &quot;Responsible person&quot;, &quot;operator&quot;: &quot;isPresentNotEmpty&quot; }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">In addition, I also defined two other operators, <strong><em>isEmpty<\/em><\/strong> and <strong><em>isNotEmpty<\/em><\/strong>. These two are <strong>always post-filters<\/strong>, they scan all matching objects in memory after the server returns them:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;isEmpty&quot; }\n\n{ &quot;property&quot;: &quot;Responsible person&quot;, &quot;operator&quot;: &quot;isNotEmpty&quot; }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Because of that post-processing, <strong><em>isEmpty<\/em><\/strong> matches objects where the property is absent OR where it is present but empty. This allows a more &#8220;complete&#8221; result set, which might be required in some specific business use-cases.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>isNotEmpty<\/em><\/strong> matches objects where the property is present AND non-empty. You might think it is exactly the same as <strong><em>isPresentNotEmpty<\/em><\/strong>, right? Well, in 99% of the cases, yes it is the same (but slower, since done as post-filter)&#8230; Except when there are bugs in M-Files ;). While developing the Business Dashboard, I found a few bugs, including one with lexicographic processing on MultiSelectLookup properties. The usage of my own operator was giving me a slightly different result and while investigating why, I found the reason and the bug in M-Files&#8217;s own operator.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In summary:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>What you want to find<\/th><th>Operator<\/th><\/tr><\/thead><tbody><tr><td>Objects where the property is present and empty OR is completely absent<\/td><td><strong><em>isEmpty<\/em><\/strong> (post-filter)<\/td><\/tr><tr><td>Objects where the property is present and empty<\/td><td><strong><em>isPresentEmpty<\/em><\/strong> (native)<\/td><\/tr><tr><td>Objects where the property has a value<\/td><td><strong><em>isPresentNotEmpty<\/em><\/strong> (native)<\/td><\/tr><tr><td>Objects where the property has a value<\/td><td><strong><em>isNotEmpty<\/em><\/strong> (post-filter alternative &#8211; sometimes more accurate)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 id=\"h-4-5-inlist-and-notinlist\" class=\"wp-block-heading\">4.5. inList and notInList<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">As the name suggests, if you are looking for multiple values, <strong><em>inList<\/em><\/strong> is what you should use. It must be an array of at least 2 elements, but you can put 50 if you want to. M-Files only support Lookup for this one, natively. Therefore, all other property types are handled as post-filters.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Agreement type&quot;, &quot;operator&quot;: &quot;inList&quot;,\n  &quot;value&quot;: &#x5B;&quot;Subcontracting Agreement&quot;, &quot;Project Agreement&quot;] }\n\n{ &quot;property&quot;: &quot;Workflow state&quot;, &quot;operator&quot;: &quot;inList&quot;,\n  &quot;value&quot;: &#x5B;&quot;In review&quot;] }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong><em>notInList<\/em><\/strong> is simply the opposite, so it just excludes all elements provided. It supports exactly the same thing as inList and works in the same way too.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Workflow state&quot;, &quot;operator&quot;: &quot;notInList&quot;,\n  &quot;value&quot;: &#x5B;&quot;Approved&quot;] }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">A subtle catch with &#8220;not&#8221; operators (<strong><em>notInList<\/em><\/strong> and similar): an object whose Lookup property is present but has no item selected satisfies &#8220;not in list&#8221; by default, because there is no value to match or compare with. If you don&#8217;t want to see these objects, then you can simply add a second filter on that same property with <strong><em>isPresentNotEmpty<\/em><\/strong>!<\/p>\n\n\n\n<h3 id=\"h-4-6-contains-and-doesnotcontain\" class=\"wp-block-heading\">4.6. contains and doesNotContain<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>contains<\/em><\/strong> is a substring match (similar to <strong><em>matchesWildcardPattern<\/em><\/strong> (c.f. below) with implicit wildcards on both sides), it finds objects where the property value includes the given string anywhere inside.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Title&quot;, &quot;operator&quot;: &quot;contains&quot;, &quot;value&quot;: &quot;NDA&quot; }\n\n{ &quot;property&quot;: &quot;Title&quot;, &quot;operator&quot;: &quot;doesNotContain&quot;,\n  &quot;value&quot;: &quot;draft&quot; }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">For Text, MultiLineText and Lookup properties, both operators are <strong>native<\/strong>. The rest is supported as <strong>post-filters<\/strong>, comparing against the string representation.<\/p>\n\n\n\n<h3 id=\"h-4-7-startswith-doesnotstartwith-endswith-doesnotendwith\" class=\"wp-block-heading\">4.7. startsWith, doesNotStartWith, endsWith, doesNotEndWith<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>startsWith<\/em><\/strong> and <strong><em>doesNotStartWith<\/em><\/strong> match objects based on the beginning of a property&#8217;s value. These are native only for Text and Lookup properties.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Name or title&quot;, &quot;operator&quot;: &quot;startsWith&quot;,\n  &quot;value&quot;: &quot;PO-&quot;    }\n\n{ &quot;property&quot;: &quot;Name or title&quot;, &quot;operator&quot;: &quot;doesNotStartWith&quot;,\n  &quot;value&quot;: &quot;DRAFT-&quot; }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong><em>endsWith<\/em><\/strong> and <strong><em>doesNotEndWith<\/em><\/strong> match based on the end of a property&#8217;s value. This doesn&#8217;t exist in M-Files, there is no equivalent and therefore, these are always <strong>post-filters<\/strong> for all property types.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Name or title&quot;, &quot;operator&quot;: &quot;endsWith&quot;,\n  &quot;value&quot;: &quot;(final)&quot; }\n\n{ &quot;property&quot;: &quot;Name or title&quot;, &quot;operator&quot;: &quot;doesNotEndWith&quot;,\n  &quot;value&quot;: &quot;(draft)&quot; }\n<\/pre><\/div>\n\n\n<h3 id=\"h-4-8-matcheswildcardpattern-and-doesnotmatchwildcardpattern\" class=\"wp-block-heading\">4.8. matchesWildcardPattern and doesNotMatchWildcardPattern<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">These are the most expressive pattern operators. The <strong><em>value<\/em><\/strong> is a regex string where <strong><em>\\<\/em><\/strong>* matches any number of characters and <strong><em>?<\/em><\/strong> matches exactly one character. This is pretty similar to the contains\/startsWith\/endsWith (and their opposite), obviously, but it is a bit more powerful if you need to match an exact pattern that you know of.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Title&quot;, &quot;operator&quot;: &quot;matchesWildcardPattern&quot;,\n  &quot;value&quot;: &quot;PO-????-2026&quot; }\n\n{ &quot;property&quot;: &quot;Title&quot;, &quot;operator&quot;: &quot;doesNotMatchWildcardPattern&quot;,\n  &quot;value&quot;: &quot;ID-*&quot; }\n<\/pre><\/div>\n\n\n<h3 id=\"h-4-9-complete-operator-reference\" class=\"wp-block-heading\">4.9. Complete operator reference<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You reached this point, so it&#8217;s time to have a cheat sheet of all operators. In the below table:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><em>Text<\/em><\/strong> and <strong><em>MultiLineText<\/em><\/strong> are NOT interchangeable<\/li>\n\n\n\n<li>&#8220;Lookup&#8221; includes both <strong><em>Lookup<\/em><\/strong> and <strong><em>MultiSelectLookup<\/em><\/strong> (these ARE interchangeable &#8211; one exception for <strong><em>between<\/em><\/strong> on MultiSelectLookup because of a bug in M-Files &#8211; the one I mentioned above)<\/li>\n\n\n\n<li>&#8220;Date&#8221; includes <strong><em>Date<\/em><\/strong>, <strong><em>Time<\/em><\/strong> and <strong><em>Timestamp<\/em><\/strong> (these ARE interchangeable &#8211; one exception for <strong><em>notEqual<\/em><\/strong> on <strong><em>Timestamp<\/em><\/strong> because of a bug in M-Files &#8211; not the same as the one mentioned above)<\/li>\n\n\n\n<li>&#8220;Numeric&#8221; includes <strong><em>Integer<\/em><\/strong>, <strong><em>Integer64<\/em><\/strong> and <strong><em>Floating<\/em><\/strong> (these ARE interchangeable) (&#8220;integer&#8221;\/&#8221;real&#8221;)<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Operator<\/th><th>Value<\/th><th>Native support for<\/th><th>Post-filter support for<\/th><th>Notes<\/th><\/tr><\/thead><tbody><tr><td><strong><em>equals<\/em><\/strong><\/td><td>string<\/td><td>Text, Lookup, Date, Numeric, Boolean<\/td><td>MultiLineText<\/td><td>Exact match<\/td><\/tr><tr><td><strong><em>notEqual<\/em><\/strong><\/td><td>string<\/td><td>Text, Lookup, Date, Numeric, Boolean<\/td><td>MultiLineText, <strong><em>Timestamp<\/em><\/strong><\/td><td>Excludes exact match. Timestamp is an exception because of a bug in M-Files<\/td><\/tr><tr><td><strong><em>lessThan<\/em><\/strong><\/td><td>string<\/td><td>Text, Lookup, Date, Numeric<\/td><td>MultiLineText<\/td><td>Boolean not supported<\/td><\/tr><tr><td><strong><em>greaterThan<\/em><\/strong><\/td><td>string<\/td><td>Text, Lookup, Date, Numeric<\/td><td>MultiLineText<\/td><td>Boolean not supported<\/td><\/tr><tr><td><strong><em>lessOrEqual<\/em><\/strong><\/td><td>string<\/td><td>Text, Lookup, Date, Numeric<\/td><td>MultiLineText<\/td><td>Boolean not supported<\/td><\/tr><tr><td><strong><em>greaterOrEqual<\/em><\/strong><\/td><td>string<\/td><td>Text, Lookup, Date, Numeric<\/td><td>MultiLineText<\/td><td>Boolean not supported<\/td><\/tr><tr><td><strong><em>between<\/em><\/strong><\/td><td>array (<strong><em>[&#8220;low&#8221;, &#8220;high&#8221;]<\/em><\/strong>)<\/td><td>Text, Lookup, Date, Numeric<\/td><td>MultiLineText<\/td><td>Two-element array, inclusive: <strong><em>low &lt;= value &lt;= high<\/em><\/strong>. Boolean not supported<\/td><\/tr><tr><td><strong><em>notBetween<\/em><\/strong><\/td><td>array (<strong><em>[&#8220;low&#8221;, &#8220;high&#8221;]<\/em><\/strong>)<\/td><td>&#8211;<\/td><td>Text, MultiLineText, Lookup, Date, Numeric<\/td><td>Two-element array, exclusive: <strong><em>value &lt; low OR value &gt; high<\/em><\/strong>. Boolean not supported<\/td><\/tr><tr><td><strong><em>inList<\/em><\/strong><\/td><td>array (<strong><em>[&#8220;a1&#8221;, &#8220;a2&#8221;, &#8220;a3&#8221;]<\/em><\/strong>)<\/td><td>Lookup<\/td><td>Text, MultiLineText, Date, Numeric, Boolean<\/td><td>&#8220;OR&#8221; logic<\/td><\/tr><tr><td><strong><em>notInList<\/em><\/strong><\/td><td>array (<strong><em>[&#8220;a1&#8221;, &#8220;a2&#8221;, &#8220;a3&#8221;]<\/em><\/strong>)<\/td><td>Lookup<\/td><td>Text, MultiLineText, Date, Numeric, Boolean<\/td><td>Inverse of <strong><em>inList<\/em><\/strong><\/td><\/tr><tr><td><strong><em>contains<\/em><\/strong><\/td><td>string<\/td><td>Text, MultiLineText, Lookup<\/td><td>Date, Numeric, Boolean<\/td><td>Implicit wildcards on both sides<\/td><\/tr><tr><td><strong><em>doesNotContain<\/em><\/strong><\/td><td>string<\/td><td>Text, MultiLineText, Lookup<\/td><td>Date, Numeric, Boolean<\/td><td>Inverse of <strong><em>contains<\/em><\/strong><\/td><\/tr><tr><td><strong><em>startsWith<\/em><\/strong><\/td><td>string<\/td><td>Text, Lookup<\/td><td>MultiLineText, Date, Numeric, Boolean<\/td><td>Prefix match<\/td><\/tr><tr><td><strong><em>doesNotStartWith<\/em><\/strong><\/td><td>string<\/td><td>Text, Lookup<\/td><td>MultiLineText, Date, Numeric, Boolean<\/td><td>Inverse of <strong><em>startsWith<\/em><\/strong><\/td><\/tr><tr><td><strong><em>endsWith<\/em><\/strong><\/td><td>string<\/td><td>&#8211;<\/td><td>All<\/td><td>Suffix match<\/td><\/tr><tr><td><strong><em>doesNotEndWith<\/em><\/strong><\/td><td>string<\/td><td>&#8211;<\/td><td>All<\/td><td>Inverse of <strong><em>endsWith<\/em><\/strong><\/td><\/tr><tr><td><strong><em>matchesWildcardPattern<\/em><\/strong><\/td><td>string<\/td><td>Text, Lookup<\/td><td>MultiLineText, Date, Numeric, Boolean<\/td><td><em><strong>*<\/strong> = any chars, <strong><em>?<\/em><\/strong> = one char, e.g. <strong><em>PO<\/em>-??-??-202?<\/strong><\/em><\/td><\/tr><tr><td><strong><em>doesNotMatchWildcardPattern<\/em><\/strong><\/td><td>string<\/td><td>Text, Lookup<\/td><td>MultiLineText, Date, Numeric, Boolean<\/td><td>Inverse of <strong><em>matchesWildcardPattern<\/em><\/strong><\/td><\/tr><tr><td><strong><em>isEmpty<\/em><\/strong><\/td><td>&#8211;<\/td><td>&#8211;<\/td><td>All<\/td><td>Property is absent OR (present AND empty)<\/td><\/tr><tr><td><strong><em>isNotEmpty<\/em><\/strong><\/td><td>&#8211;<\/td><td>&#8211;<\/td><td>All<\/td><td>Property is present AND non-empty<\/td><\/tr><tr><td><strong><em>isPresentEmpty<\/em><\/strong><\/td><td>&#8211;<\/td><td>All<\/td><td>&#8211;<\/td><td>Property is present AND empty<\/td><\/tr><tr><td><strong><em>isPresentNotEmpty<\/em><\/strong><\/td><td>&#8211;<\/td><td>All<\/td><td>&#8211;<\/td><td>Property is present AND non-empty<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 id=\"h-4-10-pattern-operators-on-date-properties\" class=\"wp-block-heading\">4.10. Pattern operators on date properties<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">All pattern operators (<strong><em>contains<\/em><\/strong>, <strong><em>startsWith<\/em><\/strong>, <strong><em>endsWith<\/em><\/strong>, <strong><em>matchesWildcardPattern<\/em><\/strong> and their negations) work on date properties via the post-filter path, comparing against the ISO <strong><em>yyyy-MM-dd<\/em><\/strong> string representation (or <strong><em>yyyy-MM-dd HH:mm<\/em><\/strong> for timestamp or <strong><em>HH:mm:ss<\/em><\/strong> for time properties). This opens up some convenient patterns, even with <strong><em>&#8220;valueType&#8221;: &#8220;literal&#8221;<\/em><\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;startsWith&quot;,\n  &quot;value&quot;: &quot;2026&quot; }\n\n{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;startsWith&quot;,\n  &quot;value&quot;: &quot;2026-04&quot; }\n\n{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;endsWith&quot;,\n  &quot;value&quot;: &quot;-31&quot; }\n\n{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;matchesWildcardPattern&quot;,\n  &quot;value&quot;: &quot;2026-??-??&quot; }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">And with <strong><em>&#8220;valueType&#8221;: &#8220;dateToken&#8221;<\/em><\/strong>, the token resolves to a full ISO date used as the exact string pattern:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;contains&quot;,\n  &quot;value&quot;: &quot;@today&quot;, &quot;valueType&quot;: &quot;dateToken&quot; }\n\n{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;startsWith&quot;,\n  &quot;value&quot;: &quot;@startOfMonth+5d&quot;, &quot;valueType&quot;: &quot;dateToken&quot; }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">A resolved token produces a full ISO date for the operators, c.f. next section for a deeper dive into dateToken details.<\/p>\n\n\n\n<h2 id=\"h-5-date-tokens-relative-filters-that-always-make-sense\" class=\"wp-block-heading\">5. Date tokens &#8211; relative filters that always make sense<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Hardcoding a date like <strong><em>&#8220;2026-01-01&#8221;<\/em><\/strong> in a filter works, but it ages badly. The dashboard built today shows different data on January 2nd than it did on December 31st, because the filter is now relative to a different &#8220;today&#8221;.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Date tokens solve this. Any string value used with <strong><em>&#8220;valueType&#8221;: &#8220;dateToken&#8221;<\/em><\/strong> is resolved to an absolute date at query execution time, so the dashboard stays meaningful as time passes.<\/p>\n\n\n\n<h3 id=\"h-5-1-anchor-tokens\" class=\"wp-block-heading\">5.1. Anchor tokens<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The following anchors are recognized:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Token<\/th><th>Resolves to<\/th><\/tr><\/thead><tbody><tr><td><strong><em>@now<\/em><\/strong><\/td><td>Current date AND time<\/td><\/tr><tr><td><strong><em>@today<\/em><\/strong><\/td><td>Midnight of the current day<\/td><\/tr><tr><td><strong><em>@startOfDay<\/em><\/strong><\/td><td>Same as <strong><em>@today<\/em><\/strong><\/td><\/tr><tr><td><strong><em>@endOfDay<\/em><\/strong><\/td><td>23:59:59 of the current day<\/td><\/tr><tr><td><strong><em>@startOfWeek<\/em><\/strong><\/td><td>Monday of the current ISO week at 00:00:00<\/td><\/tr><tr><td><strong><em>@endOfWeek<\/em><\/strong><\/td><td>Sunday of the current ISO week at 23:59:59<\/td><\/tr><tr><td><strong><em>@startOfMonth<\/em><\/strong><\/td><td>First day of the current month at 00:00:00<\/td><\/tr><tr><td><strong><em>@endOfMonth<\/em><\/strong><\/td><td>Last day of the current month at 23:59:59<\/td><\/tr><tr><td><strong><em>@startOfQuarter<\/em><\/strong><\/td><td>First day of the current quarter at 00:00:00<\/td><\/tr><tr><td><strong><em>@endOfQuarter<\/em><\/strong><\/td><td>Last day of the current quarter at 23:59:59<\/td><\/tr><tr><td><strong><em>@startOfYear<\/em><\/strong><\/td><td>January 1st of the current year at 00:00:00<\/td><\/tr><tr><td><strong><em>@endOfYear<\/em><\/strong><\/td><td>December 31st of the current year at 23:59:59<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">So <strong><em>@startOfYear<\/em><\/strong>, at the time of writing this blog (i.e. in 2026) is <strong><em>2026-01-01 00:00:00<\/em><\/strong>. Starting from January 1st 2027, the same token will automatically resolve to <strong><em>2027-01-01 00:00:00<\/em><\/strong> instead. Therefore, the dashboard rolls forward automatically.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If there is a need to add more date tokens, it&#8217;s always possible.<\/p>\n\n\n\n<h3 id=\"h-5-2-offsets-days-hours-minutes-and-seconds\" class=\"wp-block-heading\">5.2. Offsets: days, hours, minutes, and seconds<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Any anchor presented above can be followed by one or more offsets to add or subtract time:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Token<\/th><th>Meaning<\/th><\/tr><\/thead><tbody><tr><td><strong><em>@today-30d<\/em><\/strong><\/td><td>30 days ago<\/td><\/tr><tr><td><strong><em>@today+7d<\/em><\/strong><\/td><td>One week from today<\/td><\/tr><tr><td><strong><em>@startOfMonth+14d<\/em><\/strong><\/td><td>14 days into the current month<\/td><\/tr><tr><td><strong><em>@endOfYear-7d<\/em><\/strong><\/td><td>One week before year-end<\/td><\/tr><tr><td><strong><em>@today+10h<\/em><\/strong><\/td><td>10:00 today<\/td><\/tr><tr><td><strong><em>@today+10h+30m<\/em><\/strong><\/td><td>10:30 today<\/td><\/tr><tr><td><strong><em>@today+2d+10h+30m<\/em><\/strong><\/td><td>2 days from today at 10:30<\/td><\/tr><tr><td><strong><em>@now+2h<\/em><\/strong><\/td><td>Two hours from now<\/td><\/tr><tr><td><strong><em>@now-30m<\/em><\/strong><\/td><td>30 minutes ago<\/td><\/tr><tr><td><strong><em>@now+45s<\/em><\/strong><\/td><td>45 seconds from now<\/td><\/tr><tr><td><strong><em>@now-8h+30m<\/em><\/strong><\/td><td>7 hours and 30 minutes ago<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Each offset uses <strong><em>d<\/em><\/strong> for days, <strong><em>h<\/em><\/strong> for hours, <strong><em>m<\/em><\/strong> for minutes, and <strong><em>s<\/em><\/strong> for seconds. As you can see above, offsets can be chained together in any order, so <strong><em>@today+2d+10h+30m<\/em><\/strong> is valid, as is <strong><em>@now-8h+30m<\/em><\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The day offset is calendar days, not business days. There is no built-in concept of holidays in the engine as of now.<\/p>\n\n\n\n<h3 id=\"h-5-3-fixed-iso-dates-with-optional-offset\" class=\"wp-block-heading\">5.3. Fixed ISO dates (with optional offset)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A literal ISO date works as both literal as well as a date token. However, if you want to apply an offset, then only dateToken can be used. As previously mentioned, &#8220;literal&#8221; really means a literal strings, so there is no computation done on it.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;greaterOrEqual&quot;,\n  &quot;value&quot;: &quot;2026-01-01+90d&quot;, &quot;valueType&quot;: &quot;dateToken&quot; }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This resolves to <strong><em>2026-04-01 00:00:00<\/em><\/strong>, at query time. This can be useful when you want a stable absolute anchor but with an offset relative to it.<\/p>\n\n\n\n<h3 id=\"h-5-3a-when-to-use-now-instead-of-today\" class=\"wp-block-heading\">5.3a. When to use @now instead of @today<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The key difference between <strong><em>@now<\/em><\/strong> and <strong><em>@today<\/em><\/strong> is that <strong><em>@now<\/em><\/strong> captures the current time including hours, minutes, and seconds, while <strong><em>@today<\/em><\/strong> is truncated to midnight.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use <strong><em>@today<\/em><\/strong> for day-level filters (most common): &#8220;contracts expiring within 30 days&#8221;, &#8220;documents created this month&#8221;. Use <strong><em>@now<\/em><\/strong> when you need intra-day precision: &#8220;events logged in the last 2 hours&#8221;, &#8220;tasks to process in next 4 hours&#8221;. Examples:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n\/\/ All activity since this morning at 7am (a fixed time each day)\n{ &quot;property&quot;: &quot;Modified&quot;, &quot;operator&quot;: &quot;greaterOrEqual&quot;,\n  &quot;value&quot;: &quot;@today+7h&quot;, &quot;valueType&quot;: &quot;dateToken&quot; }\n\n\/\/ Flagged tasks created in the last 8 hours\n{ &quot;property&quot;: &quot;Created&quot;, &quot;operator&quot;: &quot;greaterOrEqual&quot;,\n  &quot;value&quot;: &quot;@now-8h&quot;, &quot;valueType&quot;: &quot;dateToken&quot; }\n<\/pre><\/div>\n\n\n<h2 id=\"h-6-boolean-filter-values\" class=\"wp-block-heading\">6. Boolean filter values<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For boolean-typed properties (M-Files &#8220;Boolean (yes\/no)&#8221;), the engine accepts both <strong><em>&#8220;Yes&#8221;<\/em><\/strong> \/ <strong><em>&#8220;No&#8221;<\/em><\/strong> and <strong><em>&#8220;True&#8221;<\/em><\/strong> \/ <strong><em>&#8220;False&#8221;<\/em><\/strong> (case-insensitive):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ &quot;property&quot;: &quot;Accepted&quot;, &quot;operator&quot;: &quot;equals&quot;,\n  &quot;value&quot;: &quot;Yes&quot; }\n\n{ &quot;property&quot;: &quot;Accepted&quot;, &quot;operator&quot;: &quot;equals&quot;,\n  &quot;value&quot;: &quot;True&quot; }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong><em>&#8220;Yes&#8221;<\/em><\/strong> \/ <strong><em>&#8220;No&#8221;<\/em><\/strong> is the preferred form because that is what M-Files displays in the UI and what users see in their property cards. Worth noting: the M-Files Admin label &#8220;Boolean (yes\/no)&#8221; is always English even on a localized vault. So you do not need <strong><em>&#8220;Ja&#8221;<\/em><\/strong> \/ <strong><em>&#8220;Nein&#8221;<\/em><\/strong> mappings on a German vault (at least as of today).<\/p>\n\n\n\n<h2 id=\"h-7-wrap-up\" class=\"wp-block-heading\">7. Wrap-up<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The query model covers the questions that come up in practice. <strong><em>objectType<\/em><\/strong> and <strong><em>class<\/em><\/strong> define the scope, <strong><em>filters<\/em><\/strong> narrow it with a rich set of operators spanning native server conditions and post-filter cases. Date tokens make filters relative without effort.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">What is <strong>not<\/strong> in this post: the <strong><em>aggregation<\/em><\/strong> block. That is the topic of Post 6, which covers the aggregation types, the reducers, and the multi-series <strong><em>seriesProperty<\/em><\/strong> feature. Once those are explained, every JSON block in the widget posts will make complete sense.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Want to know more about this Business Dashboard? <a href=\"https:\/\/www.dbi-services.com\/company\/contact\/\" target=\"_blank\" rel=\"noreferrer noopener\">Contact us<\/a> and we will be happy to showcase it on <a href=\"https:\/\/www.m-files.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">M-Files<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous posts of this series, I covered the anatomy of a dashboard definition and the seven widget types (KPI &amp; gauge, line &amp; area, donut, bar &amp; table) the engine supports, as of now. In this one, we will go through the Business Dashboard queries, i.e. the query section that I pretty much [&hellip;]<\/p>\n","protected":false},"author":20,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[525],"tags":[4094,4116,4118,4117,3190,4115,2046],"type_dbi":[],"class_list":["post-45175","post","type-post","status-publish","format-standard","hentry","category-enterprise-content-management","tag-business-dashboard","tag-class","tag-datetoken","tag-filters","tag-m-files","tag-objecttype","tag-query"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.8 (Yoast SEO v27.8) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>M-Files BD - Queries: objectType, class, filters, date tokens - dbi Blog<\/title>\n<meta name=\"description\" content=\"How to write queries for the M-Files Business Dashboard: objectType, class, the 13 filter operators, date tokens and relative date filters.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/m-files-bd-queries-objecttype-class-filters-date-tokens\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"M-Files BD - Queries: objectType, class, filters, date tokens\" \/>\n<meta property=\"og:description\" content=\"How to write queries for the M-Files Business Dashboard: objectType, class, the 13 filter operators, date tokens and relative date filters.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/m-files-bd-queries-objecttype-class-filters-date-tokens\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-06-20T16:32:18+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-06-20T16:32:20+00:00\" \/>\n<meta name=\"author\" content=\"Morgan Patou\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@MorganPatou\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Morgan Patou\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/m-files-bd-queries-objecttype-class-filters-date-tokens\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/m-files-bd-queries-objecttype-class-filters-date-tokens\\\/\"},\"author\":{\"name\":\"Morgan Patou\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/c4d05b25843a9bc2ab20415dae6bd2d8\"},\"headline\":\"M-Files BD &#8211; Queries: objectType, class, filters, date tokens\",\"datePublished\":\"2026-06-20T16:32:18+00:00\",\"dateModified\":\"2026-06-20T16:32:20+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/m-files-bd-queries-objecttype-class-filters-date-tokens\\\/\"},\"wordCount\":3251,\"commentCount\":0,\"keywords\":[\"Business Dashboard\",\"Class\",\"dateToken\",\"Filters\",\"M-Files\",\"objectType\",\"query\"],\"articleSection\":[\"Enterprise content management\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/m-files-bd-queries-objecttype-class-filters-date-tokens\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/m-files-bd-queries-objecttype-class-filters-date-tokens\\\/\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/m-files-bd-queries-objecttype-class-filters-date-tokens\\\/\",\"name\":\"M-Files BD - Queries: objectType, class, filters, date tokens - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-06-20T16:32:18+00:00\",\"dateModified\":\"2026-06-20T16:32:20+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/c4d05b25843a9bc2ab20415dae6bd2d8\"},\"description\":\"How to write queries for the M-Files Business Dashboard: objectType, class, the 13 filter operators, date tokens and relative date filters.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/m-files-bd-queries-objecttype-class-filters-date-tokens\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/m-files-bd-queries-objecttype-class-filters-date-tokens\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/m-files-bd-queries-objecttype-class-filters-date-tokens\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"M-Files BD &#8211; Queries: objectType, class, filters, date tokens\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/c4d05b25843a9bc2ab20415dae6bd2d8\",\"name\":\"Morgan Patou\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5d7f5bec8b597db68a09107a6f5309e3870d6296ef94fb10ead4b09454ca67e5?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5d7f5bec8b597db68a09107a6f5309e3870d6296ef94fb10ead4b09454ca67e5?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5d7f5bec8b597db68a09107a6f5309e3870d6296ef94fb10ead4b09454ca67e5?s=96&d=mm&r=g\",\"caption\":\"Morgan Patou\"},\"description\":\"Morgan Patou has over 15 years of experience in Digitalization &amp; Enterprise Content Management (ECM) systems, with a strong focus in recent years on platforms such as Alfresco, Documentum, and M-Files. He specializes in the architecture, setup, customization, and maintenance of ECM infrastructures in complex &amp; critical environments. Morgan is well-versed in both engineering and operations aspects, including high availability design, system integration, and lifecycle management. He also has a solid foundation in open-source and proprietary technologies - ranging from Apache HTTPD\\\/Tomcat, OpenLDAP or Kerberos to enterprise-grade systems like WebLogic. Morgan Patou holds an Engineering Degree in Computer Science from ENSISA (\u00c9cole Nationale Sup\u00e9rieure d'Ing\u00e9nieurs Sud Alsace) in Mulhouse, France. He is Alfresco Content Services Certified Administrator (ACSCA), Alfresco Content Services Certified Engineer (ACSCE) as well as OpenText Documentum Certified Administrator. His industry experience spans the Public Sector, IT Services, Financial Services\\\/Banking, and the Pharmaceutical industry.\",\"sameAs\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/author\\\/morgan-patou\\\/\",\"https:\\\/\\\/x.com\\\/MorganPatou\"],\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/author\\\/morgan-patou\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"M-Files BD - Queries: objectType, class, filters, date tokens - dbi Blog","description":"How to write queries for the M-Files Business Dashboard: objectType, class, the 13 filter operators, date tokens and relative date filters.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/m-files-bd-queries-objecttype-class-filters-date-tokens\/","og_locale":"en_US","og_type":"article","og_title":"M-Files BD - Queries: objectType, class, filters, date tokens","og_description":"How to write queries for the M-Files Business Dashboard: objectType, class, the 13 filter operators, date tokens and relative date filters.","og_url":"https:\/\/www.dbi-services.com\/blog\/m-files-bd-queries-objecttype-class-filters-date-tokens\/","og_site_name":"dbi Blog","article_published_time":"2026-06-20T16:32:18+00:00","article_modified_time":"2026-06-20T16:32:20+00:00","author":"Morgan Patou","twitter_card":"summary_large_image","twitter_creator":"@MorganPatou","twitter_misc":{"Written by":"Morgan Patou","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/m-files-bd-queries-objecttype-class-filters-date-tokens\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/m-files-bd-queries-objecttype-class-filters-date-tokens\/"},"author":{"name":"Morgan Patou","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/c4d05b25843a9bc2ab20415dae6bd2d8"},"headline":"M-Files BD &#8211; Queries: objectType, class, filters, date tokens","datePublished":"2026-06-20T16:32:18+00:00","dateModified":"2026-06-20T16:32:20+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/m-files-bd-queries-objecttype-class-filters-date-tokens\/"},"wordCount":3251,"commentCount":0,"keywords":["Business Dashboard","Class","dateToken","Filters","M-Files","objectType","query"],"articleSection":["Enterprise content management"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/m-files-bd-queries-objecttype-class-filters-date-tokens\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/m-files-bd-queries-objecttype-class-filters-date-tokens\/","url":"https:\/\/www.dbi-services.com\/blog\/m-files-bd-queries-objecttype-class-filters-date-tokens\/","name":"M-Files BD - Queries: objectType, class, filters, date tokens - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2026-06-20T16:32:18+00:00","dateModified":"2026-06-20T16:32:20+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/c4d05b25843a9bc2ab20415dae6bd2d8"},"description":"How to write queries for the M-Files Business Dashboard: objectType, class, the 13 filter operators, date tokens and relative date filters.","breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/m-files-bd-queries-objecttype-class-filters-date-tokens\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/m-files-bd-queries-objecttype-class-filters-date-tokens\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/m-files-bd-queries-objecttype-class-filters-date-tokens\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"M-Files BD &#8211; Queries: objectType, class, filters, date tokens"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/c4d05b25843a9bc2ab20415dae6bd2d8","name":"Morgan Patou","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/5d7f5bec8b597db68a09107a6f5309e3870d6296ef94fb10ead4b09454ca67e5?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/5d7f5bec8b597db68a09107a6f5309e3870d6296ef94fb10ead4b09454ca67e5?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5d7f5bec8b597db68a09107a6f5309e3870d6296ef94fb10ead4b09454ca67e5?s=96&d=mm&r=g","caption":"Morgan Patou"},"description":"Morgan Patou has over 15 years of experience in Digitalization &amp; Enterprise Content Management (ECM) systems, with a strong focus in recent years on platforms such as Alfresco, Documentum, and M-Files. He specializes in the architecture, setup, customization, and maintenance of ECM infrastructures in complex &amp; critical environments. Morgan is well-versed in both engineering and operations aspects, including high availability design, system integration, and lifecycle management. He also has a solid foundation in open-source and proprietary technologies - ranging from Apache HTTPD\/Tomcat, OpenLDAP or Kerberos to enterprise-grade systems like WebLogic. Morgan Patou holds an Engineering Degree in Computer Science from ENSISA (\u00c9cole Nationale Sup\u00e9rieure d'Ing\u00e9nieurs Sud Alsace) in Mulhouse, France. He is Alfresco Content Services Certified Administrator (ACSCA), Alfresco Content Services Certified Engineer (ACSCE) as well as OpenText Documentum Certified Administrator. His industry experience spans the Public Sector, IT Services, Financial Services\/Banking, and the Pharmaceutical industry.","sameAs":["https:\/\/www.dbi-services.com\/blog\/author\/morgan-patou\/","https:\/\/x.com\/MorganPatou"],"url":"https:\/\/www.dbi-services.com\/blog\/author\/morgan-patou\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/45175","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/20"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=45175"}],"version-history":[{"count":3,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/45175\/revisions"}],"predecessor-version":[{"id":45178,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/45175\/revisions\/45178"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=45175"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=45175"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=45175"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=45175"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}