Collections JS API

The Collections API returns filtered, sorted, searched and paginated data from your collections using Javascript. This article will walk you through how to use the Collections API and all of its options.

Usage

In the interest of page speed, the Collections API is not included in the page until it is initialized using Duda's JavaScript API.

var collection = await dmAPI.loadCollectionsAPI()

Once the Collections API is initialized, it can be used to fetch, filter, sort, search and paginate collection data via chaining additional methods to the data method. At a minimum, you must pass the collection name to the data method, followed by calling the get method. This configuration will return a single page of results from the specified collection.

await collection.data("collectionName").get()

Each call to the get method makes an asynchronous network request. This method returns a promise, which will be resolved with data matching the query.

Options

The Collection API supports optional method chaining to add specific filtering, sorting, and pagination when querying data. Below is an example using all optional methods.

await collection.data("collectionName")
		.where("<field>", "<operator>", "<value>")
		.orderBy("<field>","<direction>")
		.pageSize(20)
		.pageNumber(2)
		.get()

Paginating Items

Pagination is handled with two methods:

Method Name

Type

Required

Notes

pageSize

Int

No

Defaults to 50 items per page.

Max size is 100 items per page.

pageNumber

Int

No

Defaults to 0.

Filtering Items

Use the .where() method to filter the results using a provided comparison. Where takes three arguments:

ArgumentTypeRequiredDescription
fieldStringYesThe field in the collection.
operatorStringYesAvailable operators: EQ, IN, NE, NIN, GT, GTE, LT, LTE, BTWN.
valueString | Array | numberYesA value to compare.

Chaining multiple .where() calls applies an implicit AND between them:

await collection.data("orders")
  .where("status", "EQ", "open")
  .where("total", "GTE", 100)
  .get()
// => status = 'open' AND total >= 100

Filter Operators

The .where() method can utilize several different operators to filter fields based on their value. Certain operators can only be applied to fields of a specific data type.

ValueField Data TypeDescription
EQstring, numberChecks if the field is equal to the supplied value.
INstring, numberChecks if the field contains a value within the supplied array.
NEstring, numberChecks if the field is not equal to the supplied value.
NINstring, numberChecks if the field is not a value within the supplied array.
GTnumberChecks if the field is greater than the supplied value.
GTEnumberChecks if the field is greater than or equal to the supplied value.
LTnumberChecks if the field is less than the supplied value.
LTEnumberChecks if the field is less than or equal to the supplied value.
BTWNnumberCombination of LTE and GTE for convenience. Check if the field is equal or between two values. Expects a list of exactly two values.

Operator Shorthand Methods

For readability, each operator is also exposed as a shorthand method that wraps the equivalent .where() call. These can be used interchangeably with .where() both at the root of the query and inside groups (see Grouped Filtering).

MethodEquivalent .where() callNotes
.eq(field, value).where(field, "EQ", value)
.ne(field, value).where(field, "NE", value)
.gt(field, value).where(field, "GT", value)
.gte(field, value).where(field, "GTE", value)
.lt(field, value).where(field, "LT", value)
.lte(field, value).where(field, "LTE", value)
.in(field, array).where(field, "IN", array)
.nin(field, array).where(field, "NIN", array)
.btwn(field, min, max).where(field, "BTWN", [min, max])Numeric fields only. Takes min and max as separate arguments.

Example:

await collection.data("orders")
  .lt("total", 50)
  .eq("currency", "ILS")
  .get()
// => total < 50 AND currency = 'ILS'

Grouped Filtering with AND/OR

By default, all predicates at the root of a query are combined with AND. For richer boolean logic, the Collections API supports a two-level query structure combining a root combinator (AND or OR) with nested groups.

The following three methods control grouping:

MethodDescription
.root(combinator)Sets the combinator used between top-level predicates and groups. Accepts "AND" or "OR". Defaults to "AND".
.andGroup(callback)Adds a nested group whose inner predicates are combined with AND. The callback receives a group builder.
.orGroup(callback)Adds a nested group whose inner predicates are combined with OR. The callback receives a group builder.

The group builder passed to the callback supports .where() and all of the operator shorthand methods, but it does not support further nesting. Queries are limited to two levels — a root combinator plus one level of groups. Structures deeper than X OR (Y AND Z) OR (A AND B) are not supported.

Root AND with a grouped OR

status = open AND (brand IN [...] OR price < 100)

await collection.data("orders")
  .root("AND")                              // default is AND, shown here for clarity
  .where("status", "EQ", "open")            // X
  .orGroup(g => g                           // (Y OR Z)
    .where("brand", "IN", ["Nike", "Adidas"])
    .where("price", "LT", 100)
  )
  .get()

Root OR with a grouped AND

(status = open AND total >= 100) OR country = IL

await collection.data("orders")
  .root("OR")
  .andGroup(g => g
    .where("status", "EQ", "open")
    .where("total", "GTE", 100)
  )                                         // (X AND Y)
  .where("country", "EQ", "IL")             // Z
  .get()

Multiple groups at the root

X OR (Y AND Z) OR (A AND B)

await collection.data("orders")
  .root("OR")
  .where("status", "EQ", "open")            // X
  .andGroup(g => g
    .where("total", "GTE", 100)
    .where("country", "EQ", "IL")
  )                                         // (Y AND Z)
  .andGroup(g => g
    .where("segment", "EQ", "vip")
    .btwn("loyaltyPoints", 500, 1000)
  )                                         // (A AND B)
  .get()

Root-only predicates, no groups

total < 50 OR currency = ILS

await collection.data("orders")
  .root("OR")
  .lt("total", 50)
  .eq("currency", "ILS")
  .get()

Only groups, no root predicates

(city = TLV OR city = JLM) AND (payment IN [...] AND refunded != true)

await collection.data("orders")
  .root("AND")
  .orGroup(g => g
    .eq("city", "TLV")
    .eq("city", "JLM")
  )
  .andGroup(g => g
    .in("paymentMethod", ["VISA", "MC"])
    .ne("refunded", "true")
  )
  .get()

Sorting Items

Use the .orderBy() method to sort the query results. Order by takes two arguments:

ArgumentTypeRequiredNotes
fieldStringYesThe field name in the collection.
directionStringNoPossible values are “asc” and “desc”.
📘

Supported field types

You can sort by all collection field types

Searching collection

Use the .search() method to search a collection.

await collection.data("collectionName").search("<search_query>").get()
  • You can search for all string fields in a collection.
  • Search is case insensitive.
  • When searching in a collection, we check whether the search query is contained in any of the searchable fields in the collection.

Returning Specific Item Properties

Use the .select() method to only return the specific properties you need for the site or widget to function. This can improve performance for collections with a large number of properties per item. Provide each property name as a separate argument to the function.

await collection.data("orders")
  .select("id", "total", "status")
  .get()

Aggregating Items

While .data() returns individual collection items, .aggregate() returns summary statistics computed across a collection — counts, totals, averages, minimums, maximums, and facet breakdowns. Use it when you want to answer questions like "how many items fall into each category?", "what's the price range across all products?", or "what's the average rating per brand?" rather than return the underlying rows.

Typical use cases include:

  • Dynamic filter panels (e.g. Amazon-style option facets with per-choice counts)
  • Dashboard tiles (totals, averages, min/max)
  • Category or tag breakdowns
  • Global summaries across a collection

Basic Structure

Aggregations use a fluent builder terminated by .exec():

await collection.aggregate("collectionName")
  .agg("<aggregationId>", a => a
    .groupBy("<field>")
    .count()
  )
  .exec()

Each call to .agg() defines one named aggregation block. Multiple .agg() calls can be chained to compute several aggregations in a single request, and root-level filters can be applied before the aggregations run.

Building an Aggregation

Inside the .agg() callback, the builder exposes three concepts:

MethodDescription
.groupBy(...fields)Split the data into buckets, one per distinct combination of the given field values. Omit entirely to return a single global bucket with stats across the whole collection.
.unwind(...fields)Flatten an array field so each element becomes its own row before grouping. Required when grouping by (or counting) values inside an array field — see the examples below.
Metric methods (see next table)Define the statistics to compute for each bucket. Multiple metrics can be combined in one aggregation.

Metric Methods

MethodMetric TypeArgumentsNotes
.count(id?)COUNTOptional metric id (defaults to "count")Counts rows in the bucket. Does not require a field.
.sum(id, field)SUMMetric id, numeric fieldSum of the field's values across rows in the bucket.
.avg(id, field)AVGMetric id, numeric fieldAverage of the field's values across rows in the bucket.
.min(id, field)MINMetric id, numeric fieldSmallest value of the field across rows in the bucket.
.max(id, field)MAXMetric id, numeric fieldLargest value of the field across rows in the bucket.

The metric id is an arbitrary string you choose — it's the key you'll use to look up the result in the response. Multiple metrics on the same field with different ids are allowed.

Filtering Before Aggregation

Root-level filters applied before .agg() restrict which rows participate in the aggregation. The aggregate builder accepts the same predicate methods as the query API — .where(), all of the operator shorthand methods, .root(), .andGroup(), and .orGroup() — with identical semantics.

await collection.aggregate("orders")
  .gte("total", 100)
  .agg("highValueCount", a => a.count("total"))
  .exec()

Response Shape

Every aggregate call returns the same envelope:

{
  "aggregations": [
    {
      "id": "<aggregationId>",
      "buckets": [
        {
          "key": { "<groupByField>": "<value>" },
          "metrics": [
            { "id": "<metricId>", "value": <number> }
          ]
        }
      ]
    }
  ]
}

A few things to note about the response:

  • key is an object keyed by the field paths you passed to .groupBy(). When .groupBy() is omitted, key is an empty object ({}) and there's a single bucket with stats across the whole collection.
  • metrics appear in the same order they were defined on the builder.
  • Bucket order is not guaranteed. Sort client-side if you need a specific display order.

Aggregation Examples

The examples below all run against the Team Collection from the Code Examples section.

Headcount by title

Splits the collection into one bucket per Title and counts rows in each.

var result = await collection.aggregate("Team Collection")
  .agg("byTitle", a => a
    .groupBy("Title")
    .count()
  )
  .exec()

Response:

{
  "aggregations": [
    {
      "id": "byTitle",
      "buckets": [
        { "key": { "Title": "Developer" },           "metrics": [{ "id": "count", "value": 3 }] },
        { "key": { "Title": "Designer" },            "metrics": [{ "id": "count", "value": 3 }] },
        { "key": { "Title": "Product Manager" },     "metrics": [{ "id": "count", "value": 2 }] },
        { "key": { "Title": "QA Engineer" },         "metrics": [{ "id": "count", "value": 2 }] },
        { "key": { "Title": "Engineering Manager" }, "metrics": [{ "id": "count", "value": 1 }] },
        { "key": { "Title": "Data Analyst" },        "metrics": [{ "id": "count", "value": 1 }] }
      ]
    }
  ]
}

Project staffing (grouping on an array field)

Related Projects is an array field, so .unwind() is required — without it, each row would be grouped on the whole array as a single key. Unwinding flattens each person into one row per project they're on, then groups.

var result = await collection.aggregate("Team Collection")
  .agg("byProject", a => a
    .unwind("Related Projects")
    .groupBy("Related Projects")
    .count("headcount")
  )
  .exec()

The returned counts sum to more than the number of items in the collection (25 vs. 12) because most team members are on multiple projects — this is the .unwind() working as designed.

{
  "aggregations": [
    {
      "id": "byProject",
      "buckets": [
        { "key": { "Related Projects": "New Features" }, "metrics": [{ "id": "headcount", "value": 8 }] },
        { "key": { "Related Projects": "Design" },       "metrics": [{ "id": "headcount", "value": 7 }] },
        { "key": { "Related Projects": "Tech Debt" },    "metrics": [{ "id": "headcount", "value": 5 }] },
        { "key": { "Related Projects": "Performance" },  "metrics": [{ "id": "headcount", "value": 5 }] }
      ]
    }
  ]
}

Multiple metrics per bucket

Compute several statistics for the same groupings in a single pass.

var result = await collection.aggregate("Team Collection")
  .agg("experienceByRole", a => a
    .groupBy("Title")
    .count("count")
    .avg("avgYrs", "Years Experience")
    .min("minYrs", "Years Experience")
    .max("maxYrs", "Years Experience")
  )
  .exec()

Each bucket now carries four metrics. For example, the Developer bucket returns count=3, avgYrs≈6.67, minYrs=5, maxYrs=9.

Global summary (no groupBy)

Omit .groupBy() to compute statistics across the entire (filtered) collection. The response contains a single bucket with key: {}.

var result = await collection.aggregate("Team Collection")
  .agg("overall", a => a
    .count("total")
    .avg("avgYrs", "Years Experience")
  )
  .exec()

Response:

{
  "aggregations": [
    {
      "id": "overall",
      "buckets": [
        {
          "key": {},
          "metrics": [
            { "id": "total",  "value": 12 },
            { "id": "avgYrs", "value": 7.083333333333333 }
          ]
        }
      ]
    }
  ]
}

Filter + multiple aggregations in one call

Root-level predicates apply before aggregation, and multiple .agg() blocks execute in a single round trip. This example computes a summary tile and a project breakdown, both scoped to team members with at least 5 years of experience.

var result = await collection.aggregate("Team Collection")
  .root("AND")
  .gte("Years Experience", 5)
  .agg("teamSummary", a => a
    .count("total")
    .avg("avgYrs", "Years Experience")
    .max("mostYrs", "Years Experience")
    .min("leastYrs", "Years Experience")
  )
  .agg("seniorProjectCoverage", a => a
    .unwind("Related Projects")
    .groupBy("Related Projects")
    .count()
  )
  .exec()

The response contains two entries in the aggregations array — one per .agg() block — and both reflect only the 9 rows that passed the Years Experience >= 5 filter.

Code Examples

Let's assume we're calling the API with a collection called Team Collection. The response for that collection would be as follows:

[
    {
        "data": {
            "second_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/second_image_jane_smith.jpg",
            "About title": "I advise companies and NGOs in initiatives and campaigns",
            "Number": "(670)-390-7270",
            "Related Projects": ["Design", "Performance", "New Features"],
            "Join Date": "2023-09-19T00:00",
            "main_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/main_image_jane_smith.jpg",
            "About description": "This is the text area for a paragraph describing this service. You may want to give examples of the service and who may be able to benefit from it.",
            "Work experience": "<b>2020-2021</b><br/>\nAdvisor, South Company<br/>\nIn this position, I led a team of more than 40 professional and volunteer staff members, from various company departments.",
            "Title": "Product Manager",
            "email": "[email protected]",
            "Name": "Jane Smith",
            "Years Experience": 8
        },
        "page_item_url": "1_jane_smith"
    },
    {
        "data": {
            "second_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/second_image_john_brown.jpg",
            "About title": "I advise companies and NGOs in initiatives and campaigns",
            "Number": "(671)-390-7270",
            "Related Projects": ["New Features", "Performance", "Tech Debt"],
            "Join Date": "2023-08-03T00:00",
            "main_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/main_image_john_brown.jpg",
            "About description": "This is the text area for a paragraph describing this service. You may want to give examples of the service and who may be able to benefit from it.",
            "Work experience": "<b>2019-2020</b><br/>\nAdvisor, South Company<br/>\nIn this position, I led a team of more than 40 professional and volunteer staff members, from various company departments.",
            "Title": "Developer",
            "email": "[email protected]",
            "Name": "John Brown",
            "Years Experience": 5
        },
        "page_item_url": "2_john_brown"
    },
    {
        "data": {
            "second_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/second_image_helen_jameson.jpg",
            "About title": "I advise companies and NGOs in initiatives and campaigns",
            "Number": "(672)-390-7270",
            "Related Projects": ["Design", "New Features"],
            "Join Date": "2023-09-30T00:00",
            "main_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/main_image_helen_jameson.jpg",
            "About description": "This is the text area for a paragraph describing this service. You may want to give examples of the service and who may be able to benefit from it.",
            "Work experience": "<b>2018-2019</b><br/>\nAdvisor, South Company<br/>\nIn this position, I led a team of more than 40 professional and volunteer staff members, from various company departments.",
            "Title": "Designer",
            "email": "[email protected]",
            "Name": "Helen Jameson",
            "Years Experience": 6
        },
        "page_item_url": "3_helen_jameson"
    },
    {
        "data": {
            "second_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/second_image_tom_philips.jpg",
            "About title": "I advise companies and NGOs in initiatives and campaigns",
            "Number": "(673)-390-7270",
            "Related Projects": ["Tech Debt", "New Features"],
            "Join Date": "2023-09-17T00:00",
            "main_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/main_image_tom_philips.jpg",
            "About description": "This is the text area for a paragraph describing this service. You may want to give examples of the service and who may be able to benefit from it.",
            "Work experience": "<b>2022-2023</b><br/>\nAdvisor, South Company<br/>\nIn this position, I led a team of more than 40 professional and volunteer staff members, from various company departments.",
            "Title": "QA Engineer",
            "email": "[email protected]",
            "Name": "Tom Phillips",
            "Years Experience": 3
        },
        "page_item_url": "4_tom_phillips"
    },
    {
        "data": {
            "second_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/second_image_maria_garcia.jpg",
            "About title": "I advise companies and NGOs in initiatives and campaigns",
            "Number": "(674)-390-7270",
            "Related Projects": ["Performance", "Tech Debt"],
            "Join Date": "2022-06-15T00:00",
            "main_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/main_image_maria_garcia.jpg",
            "About description": "This is the text area for a paragraph describing this service. You may want to give examples of the service and who may be able to benefit from it.",
            "Work experience": "<b>2017-2022</b><br/>\nEngineering Manager, West Company<br/>\nLed cross-functional teams across backend infrastructure and platform reliability.",
            "Title": "Engineering Manager",
            "email": "[email protected]",
            "Name": "Maria Garcia",
            "Years Experience": 12
        },
        "page_item_url": "5_maria_garcia"
    },
    {
        "data": {
            "second_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/second_image_david_kim.jpg",
            "About title": "I advise companies and NGOs in initiatives and campaigns",
            "Number": "(675)-390-7270",
            "Related Projects": ["New Features", "Design"],
            "Join Date": "2023-03-22T00:00",
            "main_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/main_image_david_kim.jpg",
            "About description": "This is the text area for a paragraph describing this service. You may want to give examples of the service and who may be able to benefit from it.",
            "Work experience": "<b>2020-2023</b><br/>\nData Analyst, North Company<br/>\nBuilt dashboards and experimentation tooling used across the product org.",
            "Title": "Data Analyst",
            "email": "[email protected]",
            "Name": "David Kim",
            "Years Experience": 4
        },
        "page_item_url": "6_david_kim"
    },
    {
        "data": {
            "second_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/second_image_sarah_chen.jpg",
            "About title": "I advise companies and NGOs in initiatives and campaigns",
            "Number": "(676)-390-7270",
            "Related Projects": ["Design"],
            "Join Date": "2023-11-05T00:00",
            "main_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/main_image_sarah_chen.jpg",
            "About description": "This is the text area for a paragraph describing this service. You may want to give examples of the service and who may be able to benefit from it.",
            "Work experience": "<b>2019-2023</b><br/>\nSenior Designer, East Company<br/>\nDesign systems, component libraries, and product illustration.",
            "Title": "Designer",
            "email": "[email protected]",
            "Name": "Sarah Chen",
            "Years Experience": 7
        },
        "page_item_url": "7_sarah_chen"
    },
    {
        "data": {
            "second_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/second_image_michael_oconnor.jpg",
            "About title": "I advise companies and NGOs in initiatives and campaigns",
            "Number": "(677)-390-7270",
            "Related Projects": ["Tech Debt", "Performance"],
            "Join Date": "2022-11-28T00:00",
            "main_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/main_image_michael_oconnor.jpg",
            "About description": "This is the text area for a paragraph describing this service. You may want to give examples of the service and who may be able to benefit from it.",
            "Work experience": "<b>2018-2022</b><br/>\nBackend Developer, South Company<br/>\nDistributed systems, queueing infrastructure, and observability work.",
            "Title": "Developer",
            "email": "[email protected]",
            "Name": "Michael O'Connor",
            "Years Experience": 9
        },
        "page_item_url": "8_michael_oconnor"
    },
    {
        "data": {
            "second_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/second_image_priya_patel.jpg",
            "About title": "I advise companies and NGOs in initiatives and campaigns",
            "Number": "(678)-390-7270",
            "Related Projects": ["New Features", "Design"],
            "Join Date": "2023-05-10T00:00",
            "main_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/main_image_priya_patel.jpg",
            "About description": "This is the text area for a paragraph describing this service. You may want to give examples of the service and who may be able to benefit from it.",
            "Work experience": "<b>2018-2023</b><br/>\nProduct Manager, West Company<br/>\nLed roadmap and discovery work for a two-sided marketplace.",
            "Title": "Product Manager",
            "email": "[email protected]",
            "Name": "Priya Patel",
            "Years Experience": 10
        },
        "page_item_url": "9_priya_patel"
    },
    {
        "data": {
            "second_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/second_image_james_wilson.jpg",
            "About title": "I advise companies and NGOs in initiatives and campaigns",
            "Number": "(679)-390-7270",
            "Related Projects": ["New Features"],
            "Join Date": "2023-02-14T00:00",
            "main_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/main_image_james_wilson.jpg",
            "About description": "This is the text area for a paragraph describing this service. You may want to give examples of the service and who may be able to benefit from it.",
            "Work experience": "<b>2020-2023</b><br/>\nQA Engineer, North Company<br/>\nTest automation frameworks and release validation.",
            "Title": "QA Engineer",
            "email": "[email protected]",
            "Name": "James Wilson",
            "Years Experience": 4
        },
        "page_item_url": "10_james_wilson"
    },
    {
        "data": {
            "second_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/second_image_emma_thompson.jpg",
            "About title": "I advise companies and NGOs in initiatives and campaigns",
            "Number": "(680)-390-7270",
            "Related Projects": ["Design", "New Features", "Tech Debt"],
            "Join Date": "2023-10-01T00:00",
            "main_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/main_image_emma_thompson.jpg",
            "About description": "This is the text area for a paragraph describing this service. You may want to give examples of the service and who may be able to benefit from it.",
            "Work experience": "<b>2019-2023</b><br/>\nFull-Stack Developer, East Company<br/>\nEnd-to-end feature delivery across web and mobile surfaces.",
            "Title": "Developer",
            "email": "[email protected]",
            "Name": "Emma Thompson",
            "Years Experience": 6
        },
        "page_item_url": "11_emma_thompson"
    },
    {
        "data": {
            "second_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/second_image_carlos_rodriguez.jpg",
            "About title": "I advise companies and NGOs in initiatives and campaigns",
            "Number": "(681)-390-7270",
            "Related Projects": ["Performance", "Design"],
            "Join Date": "2022-08-20T00:00",
            "main_image": "https://static-cdn.multiscreensite.com/dynamicpages/defaultCollection/Team_member/main_image_carlos_rodriguez.jpg",
            "About description": "This is the text area for a paragraph describing this service. You may want to give examples of the service and who may be able to benefit from it.",
            "Work experience": "<b>2017-2022</b><br/>\nPrincipal Designer, South Company<br/>\nBrand, motion, and design ops leadership.",
            "Title": "Designer",
            "email": "[email protected]",
            "Name": "Carlos Rodriguez",
            "Years Experience": 11
        },
        "page_item_url": "12_carlos_rodriguez"
    }
]

Getting a specific row

await collection.data("Team Collection").where("Name", "EQ", "John Brown").get()

Getting all rows that match a multi-select field

await collection.data("Team Collection").where("Related Projects", "IN", ["Design", "Performance"]).get()

Sorting by Date

await collection.data("Team Collection").orderBy("Join Date", "asc").get()

Using operator shorthand

await collection.data("Team Collection").eq("Title", "Developer").get()

Filtering a numeric field with BTWN (team members with 5–10 years of experience)

await collection.data("Team Collection").btwn("Years Experience", 5, 10).get()

Combining paging, sorting, and field selection

await collection.data("Team Collection")
  .pageNumber(2)
  .pageSize(50)
  .orderBy("Join Date", "desc")
  .select("Name", "Title", "Join Date")
  .get()

Root OR with a grouped AND (senior developers, or anyone staffed on Tech Debt)

await collection.data("Team Collection")
  .root("OR")
  .andGroup(g => g
    .eq("Title", "Developer")
    .gte("Years Experience", 8)
  )
  .in("Related Projects", ["Tech Debt"])
  .get()