Search AGT

Prerequisite to test following examples is to have an API key with permissions:

Path Methods ACL
/aggregates/core\.aggregate POST off
/resources/writer POST off
/resources/news\.article POST off
/aggregates/agt\.writer-latest-articles GET off
/aggregates/agt\.writer-latest-articles/[0-9a-fA-F]{24}-[0-9]+ GET off
/aggregates/agt\.writer-latest-articles/relationships/articles GET off
/aggregates/agt\.writer-article-overview GET off

Search AGT documention is explained using a test model created by the following requests.

Create agt.writer-latest-articles aggregate using API request:

curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-d '
{
"data": {
  "type": "core.aggregate",
  "attributes": {
    "input-type": "news.article",
    "output-type": "agt.writer-latest-articles",
    "parameters": {
       "articleCount": 5
    },
    "pipeline": [{
      "sort": "-published"
    }, {
      "group": {
        "id": "$author.id",
        "articles": {
          "$push": {
            "type": "news.article",
            "id": { "$toString": "$id" }
          }
        }
      }
    }, {
      "project": {
        "id": { "$toObjectId": "$id" },
        "author": {
          "type": "writer",
          "id": "$id"
        },
        "articles": {
          "$slice": [ "$articles", "$$parameters.articleCount" ]
        }
      }
    }, {
      "output": {
        "relationships": [ "author", "articles" ]
      }
    }]
  }
}
}' \
-X POST https://api.jazer.io/aggregates/core.aggregate

Create agt.writer-article-overview aggregate using API request:

curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-d '
{
"data": {
  "type": "core.aggregate",
  "attributes": {
    "input-type": "news.article",
    "output-type": "agt.writer-article-overview",
    "pipeline": [{
      "group": {
        "id": "$author.id",
        "last-published-date": { "$max": "$published" },
        "article-count": { "$sum": 1 }
      }
    }, {
      "project": {
        "last-published-date": "$last-published-date",
        "article-count": "$article-count",
        "author": {
          "type": "writer",
          "id": { "$toString": "$id" }
        },
        "latest-articles": {
          "type": "agt.writer-latest-articles",
          "id": { "$toString": "$id" }
        }
      }
    }, {
      "output": {
        "attributes": [ "last-published-date", "article-count" ],
        "relationships": [ "author", "latest-articles" ]
      }
    }]
  }
}
}' \
-X POST https://api.jazer.io/aggregates/core.aggregate

Using following API request create a few writer documents each with a different name:

curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-d '
{
  "data": {
    "type": "writer",
    "attributes": {
      "name": "John Smith"
    }
  }
}' \
-X POST https://api.jazer.io/resources/news.article

Create a few news.article document with a different title linking previously created writer documents using API request:

curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-d '
{
  "data": {
    "type": "news.article",
    "attributes": {
      "title": "Future is now",
      "published": { "$date": "2019-03-20T15:22:40Z" }
    },
    "relationships": {
      "author": {
        "data": {
          "type": "writer",
          "id": "<WRITER_ID>"
        }
      }
    }
  }
}' \
-X POST https://api.jazer.io/resources/news.article

Documents

Fetching AGT documents of an AGT type is available using GET method on the collection path: /aggregates/<AGT_TYPE>.

Test model contains agt.writer-latest-articles documents where its ID is writer ID. To fetch documents of type agt.writer-latest-articles following API request can be used:

curl -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/aggregates/agt.writer-latest-articles

The response contains agt.writer-latest-articles documents:

{
  "meta": {
    "count": 2
  },
  "data": [
    {
      "type": "agt.writer-latest-articles",
      "id": "5cdde75e2c387e2423a0f389",
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/author"
          }
        },
        "articles": {
          "data": [
            {
              "type": "news.article",
              "id": "5cddeaf62c387e2423a0f3b8"
            },
            {
              "type": "news.article",
              "id": "5cddeada2c387e2423a0f3b4"
            },
            {
              "type": "news.article",
              "id": "5cdde9792c387e2423a0f3a5"
            },
            {
              "type": "news.article",
              "id": "5cdde9572c387e2423a0f3a1"
            }
          ],
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/relationships/articles",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/articles"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389"
      }
    },
    {
      "type": "agt.writer-latest-articles",
      "id": "5cdde73a2c387e2423a0f385",
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/author"
          }
        },
        "articles": {
          "data": [
            {
              "type": "news.article",
              "id": "5cddeb242c387e2423a0f3bc"
            },
            {
              "type": "news.article",
              "id": "5cdde8e32c387e2423a0f397"
            },
            {
              "type": "news.article",
              "id": "5cdde8632c387e2423a0f393"
            },
            {
              "type": "news.article",
              "id": "5cdde8452c387e2423a0f38f"
            }
          ],
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/relationships/articles",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/articles"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385"
      }
    }
  ],
  "links": {
    "first": "https://api.jazer.io/aggregates/agt.writer-latest-articles?page[offset]=0&page[limit]=20",
    "last": "https://api.jazer.io/aggregates/agt.writer-latest-articles?page[offset]=0&page[limit]=20",
    "prev": null,
    "next": null
  }
}

There are two writer documents present where each has four news.article documents. This means agt.writer-latest-articles will contain 2 documents linking all articles since default article count is 5. Metadata contains property count which holds value of a total number of documents accross all pages.

Filtering

Query parameter filter supports AGT collection filtering. Two syntaxes are supported:

  • filter[*] - filter applies to an entire AGT document
  • filter[<FIELD>] - filter applies only to an AGT document field

Example:

filter[*]={ "$and": [{ "author.type": "writer" }, { "articles": { "$size": 0 } }] }

produces the same result as:

filter[author.type]={ "$eq": "writer" }&filter[articles]={ "$size": 0 }

Complete API request with encoded filter[*] query parameter is:

curl --globoff -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET 'https://api.jazer.io/aggregates/agt.writer-latest-articles?filter[*]=%7B%22%24and%22%3A%5B%7B%22author.type%22%3A%22writer%22%7D%2C%7B%22articles%22%3A%7B%22%24size%22%3A0%7D%7D%5D%7D'

Response is empty since there are no writer documents with zero news.article documents:

{
  "meta": {
    "count": 0
  },
  "data": [],
  "links": {
      "first": null,
      "prev": null,
      "next": null,
      "last": null
  }
}

Note

Aggregate collections support same filter operators as persisted collections mentioned in Resource Search.

Fields

Aggregation pipeline can customize which fields will be present in AGT documents. Query parameter fields supports further AGT document field customization.

Syntax: fields[<AGT_DOCUMENT_TYPE>]=<FIELD_NAMES>, where FIELD_NAMES is a comma-separated list of field names.

Example:

AGT documents of type agt.writer-latest-articles have fields: author and articles. To fetch agt.writer-latest-articles documents with only author field, omitting articles, following API request can be used:

curl --globoff -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET 'https://api.jazer.io/aggregates/agt.writer-latest-articles?fields[agt.writer-latest-articles]=author'

The response contains projected agt.writer-latest-articles documents:

{
  "meta": {
    "count": 2
  },
  "data": [
    {
      "type": "agt.writer-latest-articles",
      "id": "5cdde75e2c387e2423a0f389",
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389"
      }
    },
    {
      "type": "agt.writer-latest-articles",
      "id": "5cdde73a2c387e2423a0f385",
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385"
      }
    }
  ],
  "links": {
    "first": "https://api.jazer.io/aggregates/agt.writer-latest-articles?fields%5Bagt.writer-latest-articles%5D=author&page[offset]=0&page[limit]=20",
    "last": "https://api.jazer.io/aggregates/agt.writer-latest-articles?fields%5Bagt.writer-latest-articles%5D=author&page[offset]=0&page[limit]=20",
    "prev": null,
    "next": null
  }
}

Inclusion

An AGT document can specify related documents using relationships. Related documents can be included in the response alongside primary documents using query parameter include. The syntax is: include=<RELATIONSHIP_PATHS>, where RELATIONSHIP_PATHS is a comma-separated list of relationship paths.

To-one relationship inclusion

Example agt.writer-latest-articles documents contain a to-one relationship author. The following request will instruct the system to include documents referenced in relationship author alongside primary agt.writer-latest-articles documents:

curl -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/aggregates/agt.writer-latest-articles?include=author

Response will contain primary and included documents:

{
  "meta": {
    "count": 2
  },
  "data": [
    {
      "type": "agt.writer-latest-articles",
      "id": "5cdde75e2c387e2423a0f389",
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/author"
          }
        },
        "articles": {
          "data": [
            {
              "type": "news.article",
              "id": "5cddeaf62c387e2423a0f3b8"
            },
            {
              "type": "news.article",
              "id": "5cddeada2c387e2423a0f3b4"
            },
            {
              "type": "news.article",
              "id": "5cdde9792c387e2423a0f3a5"
            },
            {
              "type": "news.article",
              "id": "5cdde9572c387e2423a0f3a1"
            }
          ],
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/relationships/articles",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/articles"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389"
      }
    },
    {
      "type": "agt.writer-latest-articles",
      "id": "5cdde73a2c387e2423a0f385",
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/author"
          }
        },
        "articles": {
          "data": [
            {
              "type": "news.article",
              "id": "5cddeb242c387e2423a0f3bc"
            },
            {
              "type": "news.article",
              "id": "5cdde8e32c387e2423a0f397"
            },
            {
              "type": "news.article",
              "id": "5cdde8632c387e2423a0f393"
            },
            {
              "type": "news.article",
              "id": "5cdde8452c387e2423a0f38f"
            }
          ],
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/relationships/articles",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/articles"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385"
      }
    }
  ],
  "included": [
    {
      "type": "writer",
      "id": "5cdde73a2c387e2423a0f385",
      "attributes": {
        "name": "John Smith"
      },
      "links": {
        "self": "https://api.jazer.io/resources/writer/5cdde73a2c387e2423a0f385"
      }
    },
    {
      "type": "writer",
      "id": "5cdde75e2c387e2423a0f389",
      "attributes": {
        "name": "Alice Smart"
      },
      "links": {
        "self": "https://api.jazer.io/resources/writer/5cdde75e2c387e2423a0f389"
      }
    }
  ],
  "links": {
    "first": "https://api.jazer.io/aggregates/agt.writer-latest-articles?include=author&page[offset]=0&page[limit]=20",
    "last": "https://api.jazer.io/aggregates/agt.writer-latest-articles?include=author&page[offset]=0&page[limit]=20",
    "prev": null,
    "next": null
  }
}

To-many relationship inclusion

Example agt.writer-latest-articles documents contain a to-many relationship articles. The following request will instruct the system to include all documents referenced in relationship articles alongside primary agt.writer-latest-articles documents:

curl -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/aggregates/agt.writer-latest-articles?include=articles

The response is:

{
  "meta": {
    "count": 2
  },
  "data": [
    {
      "type": "agt.writer-latest-articles",
      "id": "5cdde75e2c387e2423a0f389",
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/author"
          }
        },
        "articles": {
          "data": [
            {
              "type": "news.article",
              "id": "5cddeaf62c387e2423a0f3b8"
            },
            {
              "type": "news.article",
              "id": "5cddeada2c387e2423a0f3b4"
            },
            {
              "type": "news.article",
              "id": "5cdde9792c387e2423a0f3a5"
            },
            {
              "type": "news.article",
              "id": "5cdde9572c387e2423a0f3a1"
            }
          ],
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/relationships/articles",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/articles"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389"
      }
    },
    {
      "type": "agt.writer-latest-articles",
      "id": "5cdde73a2c387e2423a0f385",
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/author"
          }
        },
        "articles": {
          "data": [
            {
              "type": "news.article",
              "id": "5cddeb242c387e2423a0f3bc"
            },
            {
              "type": "news.article",
              "id": "5cdde8e32c387e2423a0f397"
            },
            {
              "type": "news.article",
              "id": "5cdde8632c387e2423a0f393"
            },
            {
              "type": "news.article",
              "id": "5cdde8452c387e2423a0f38f"
            }
          ],
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/relationships/articles",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/articles"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385"
      }
    }
  ],
  "included": [
    {
      "type": "news.article",
      "id": "5cdde8452c387e2423a0f38f",
      "attributes": {
        "name": "Things are good",
        "published": "2019-01-15T10:06:00.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cdde8452c387e2423a0f38f/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cdde8452c387e2423a0f38f/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cdde8452c387e2423a0f38f"
      }
    },
    {
      "type": "news.article",
      "id": "5cdde8632c387e2423a0f393",
      "attributes": {
        "name": "One step forward",
        "published": "2019-01-25T14:21:33.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cdde8632c387e2423a0f393/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cdde8632c387e2423a0f393/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cdde8632c387e2423a0f393"
      }
    },
    {
      "type": "news.article",
      "id": "5cdde8e32c387e2423a0f397",
      "attributes": {
        "name": "Election results",
        "published": "2019-02-01T09:47:23.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cdde8e32c387e2423a0f397/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cdde8e32c387e2423a0f397/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cdde8e32c387e2423a0f397"
      }
    },
    {
      "type": "news.article",
      "id": "5cdde9572c387e2423a0f3a1",
      "attributes": {
        "name": "What is new in 2019.",
        "published": "2019-01-02T09:47:23.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cdde9572c387e2423a0f3a1/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cdde9572c387e2423a0f3a1/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cdde9572c387e2423a0f3a1"
      }
    },
    {
      "type": "news.article",
      "id": "5cdde9792c387e2423a0f3a5",
      "attributes": {
        "name": "Hottest places to visit",
        "published": "2019-02-18T08:15:54.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cdde9792c387e2423a0f3a5/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cdde9792c387e2423a0f3a5/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cdde9792c387e2423a0f3a5"
      }
    },
    {
      "type": "news.article",
      "id": "5cddeada2c387e2423a0f3b4",
      "attributes": {
        "name": "What not to buy",
        "published": "2019-03-02T13:02:17.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cddeada2c387e2423a0f3b4/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cddeada2c387e2423a0f3b4/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cddeada2c387e2423a0f3b4"
      }
    },
    {
      "type": "news.article",
      "id": "5cddeaf62c387e2423a0f3b8",
      "attributes": {
        "name": "Our children",
        "published": "2019-03-07T10:14:44.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cddeaf62c387e2423a0f3b8/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cddeaf62c387e2423a0f3b8/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cddeaf62c387e2423a0f3b8"
      }
    },
    {
      "type": "news.article",
      "id": "5cddeb242c387e2423a0f3bc",
      "attributes": {
        "name": "Future is now",
        "published": "2019-03-20T15:22:40.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cddeb242c387e2423a0f3bc/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cddeb242c387e2423a0f3bc/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cddeb242c387e2423a0f3bc"
      }
    }
  ],
  "links": {
    "first": "https://api.jazer.io/aggregates/agt.writer-latest-articles?include=articles&page[offset]=0&page[limit]=20",
    "last": "https://api.jazer.io/aggregates/agt.writer-latest-articles?include=articles&page[offset]=0&page[limit]=20",
    "prev": null,
    "next": null
  }
}

Deeply nested relationship inclusion

Example agt.writer-article-overview documents contain a to-many relationship latest-articles which contains references to agt.writer-latest-articles documents. Each agt.writer-latest-articles document contains a to-many relationship articles which points to documents of type news.article.

Fetching agt.writer-article-overview documents with included related documents under relationship latest-articles and of those documents related documents under relationship articles, following API request can be used:

curl -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/aggregates/agt.writer-article-overview?include=latest-articles.articles

The response is:

{
  "meta": {
    "count": 2
  },
  "data": [
    {
      "type": "agt.writer-article-overview",
      "id": "5cdde75e2c387e2423a0f389",
      "attributes": {
        "last-published-date": "2019-03-07T10:14:44.000Z",
        "article-count": 4
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde75e2c387e2423a0f389/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde75e2c387e2423a0f389/author"
          }
        },
        "latest-articles": {
          "data": {
            "type": "agt.writer-latest-articles",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde75e2c387e2423a0f389/relationships/latest-articles",
            "related": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde75e2c387e2423a0f389/latest-articles"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde75e2c387e2423a0f389"
      }
    },
    {
      "type": "agt.writer-article-overview",
      "id": "5cdde73a2c387e2423a0f385",
      "attributes": {
        "last-published-date": "2019-03-20T15:22:40.000Z",
        "article-count": 4
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde73a2c387e2423a0f385/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde73a2c387e2423a0f385/author"
          }
        },
        "latest-articles": {
          "data": {
            "type": "agt.writer-latest-articles",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde73a2c387e2423a0f385/relationships/latest-articles",
            "related": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde73a2c387e2423a0f385/latest-articles"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde73a2c387e2423a0f385"
      }
    }
  ],
  "included": [
    {
      "type": "news.article",
      "id": "5cdde8452c387e2423a0f38f",
      "attributes": {
        "name": "Things are good",
        "published": "2019-01-15T10:06:00.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cdde8452c387e2423a0f38f/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cdde8452c387e2423a0f38f/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cdde8452c387e2423a0f38f"
      }
    },
    {
      "type": "news.article",
      "id": "5cdde8632c387e2423a0f393",
      "attributes": {
        "name": "One step forward",
        "published": "2019-01-25T14:21:33.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cdde8632c387e2423a0f393/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cdde8632c387e2423a0f393/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cdde8632c387e2423a0f393"
      }
    },
    {
      "type": "news.article",
      "id": "5cdde8e32c387e2423a0f397",
      "attributes": {
        "name": "Election results",
        "published": "2019-02-01T09:47:23.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cdde8e32c387e2423a0f397/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cdde8e32c387e2423a0f397/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cdde8e32c387e2423a0f397"
      }
    },
    {
      "type": "news.article",
      "id": "5cdde9572c387e2423a0f3a1",
      "attributes": {
        "name": "What is new in 2019.",
        "published": "2019-01-02T09:47:23.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cdde9572c387e2423a0f3a1/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cdde9572c387e2423a0f3a1/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cdde9572c387e2423a0f3a1"
      }
    },
    {
      "type": "news.article",
      "id": "5cdde9792c387e2423a0f3a5",
      "attributes": {
        "name": "Hottest places to visit",
        "published": "2019-02-18T08:15:54.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cdde9792c387e2423a0f3a5/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cdde9792c387e2423a0f3a5/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cdde9792c387e2423a0f3a5"
      }
    },
    {
      "type": "news.article",
      "id": "5cddeada2c387e2423a0f3b4",
      "attributes": {
        "name": "What not to buy",
        "published": "2019-03-02T13:02:17.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cddeada2c387e2423a0f3b4/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cddeada2c387e2423a0f3b4/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cddeada2c387e2423a0f3b4"
      }
    },
    {
      "type": "news.article",
      "id": "5cddeaf62c387e2423a0f3b8",
      "attributes": {
        "name": "Our children",
        "published": "2019-03-07T10:14:44.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cddeaf62c387e2423a0f3b8/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cddeaf62c387e2423a0f3b8/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cddeaf62c387e2423a0f3b8"
      }
    },
    {
      "type": "news.article",
      "id": "5cddeb242c387e2423a0f3bc",
      "attributes": {
        "name": "Future is now",
        "published": "2019-03-20T15:22:40.000Z"
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/resources/news.article/5cddeb242c387e2423a0f3bc/relationships/author",
            "related": "https://api.jazer.io/resources/news.article/5cddeb242c387e2423a0f3bc/author"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/resources/news.article/5cddeb242c387e2423a0f3bc"
      }
    },
    {
      "type": "agt.writer-latest-articles",
      "id": "5cdde73a2c387e2423a0f385",
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/author"
          }
        },
        "articles": {
          "data": [
            {
              "type": "news.article",
              "id": "5cddeb242c387e2423a0f3bc"
            },
            {
              "type": "news.article",
              "id": "5cdde8e32c387e2423a0f397"
            },
            {
              "type": "news.article",
              "id": "5cdde8632c387e2423a0f393"
            },
            {
              "type": "news.article",
              "id": "5cdde8452c387e2423a0f38f"
            }
          ],
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/relationships/articles",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/articles"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385"
      }
    },
    {
      "type": "agt.writer-latest-articles",
      "id": "5cdde75e2c387e2423a0f389",
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/author"
          }
        },
        "articles": {
          "data": [
            {
              "type": "news.article",
              "id": "5cddeaf62c387e2423a0f3b8"
            },
            {
              "type": "news.article",
              "id": "5cddeada2c387e2423a0f3b4"
            },
            {
              "type": "news.article",
              "id": "5cdde9792c387e2423a0f3a5"
            },
            {
              "type": "news.article",
              "id": "5cdde9572c387e2423a0f3a1"
            }
          ],
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/relationships/articles",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/articles"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389"
      }
    }
  ],
  "links": {
    "first": "https://api.jazer.io/aggregates/agt.writer-article-overview?include=latest-articles.articles&page[offset]=0&page[limit]=20",
    "last": "https://api.jazer.io/aggregates/agt.writer-article-overview?include=latest-articles.articles&page[offset]=0&page[limit]=20",
    "prev": null,
    "next": null
  }
}

Inclusion security

The system will not include a document for which client does not have permission to access. API key must have permission path which matches document endpoint with allowed GET method.

A document with relationship with type agt.writer-latest-articles and ID 5cdde73a2c387e2423a0f385 requires API key to have a path like /aggregates/agt\.writer-latest-articles/[0-9a-fA-F]{24}-[0-9]+ and allowed GET method. Basically, if the client can read the document by ID then it can be included.

Sorting

AGT collections support sorting with query parameter sort. Syntax: sort=<ATTRIBUTE_NAMES>, where ATTRIBUTE_NAMES is a comma-separated list of attributes to sort by. Default sort order is ascending. Prefix attribute name with - (minus) to sort in descending order.

Example API request fetches agt.writer-article-overview documents sorted by last-published-date in the descending order:

curl -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET 'https://api.jazer.io/aggregates/agt.writer-article-overview?sort=-last-published-date'

The response is:

{
  "meta": {
    "count": 2
  },
  "data": [
    {
      "type": "agt.writer-article-overview",
      "id": "5cdde73a2c387e2423a0f385",
      "attributes": {
        "last-published-date": "2019-03-20T15:22:40.000Z",
        "article-count": 4
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde73a2c387e2423a0f385/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde73a2c387e2423a0f385/author"
          }
        },
        "latest-articles": {
          "data": {
            "type": "agt.writer-latest-articles",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde73a2c387e2423a0f385/relationships/latest-articles",
            "related": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde73a2c387e2423a0f385/latest-articles"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde73a2c387e2423a0f385"
      }
    },
    {
      "type": "agt.writer-article-overview",
      "id": "5cdde75e2c387e2423a0f389",
      "attributes": {
        "last-published-date": "2019-03-07T10:14:44.000Z",
        "article-count": 4
      },
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde75e2c387e2423a0f389/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde75e2c387e2423a0f389/author"
          }
        },
        "latest-articles": {
          "data": {
            "type": "agt.writer-latest-articles",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde75e2c387e2423a0f389/relationships/latest-articles",
            "related": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde75e2c387e2423a0f389/latest-articles"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-article-overview/5cdde75e2c387e2423a0f389"
      }
    }
  ],
  "links": {
    "first": "https://api.jazer.io/aggregates/agt.writer-article-overview?sort=-last-published-date&page[offset]=0&page[limit]=20",
    "last": "https://api.jazer.io/aggregates/agt.writer-article-overview?sort=-last-published-date&page[offset]=0&page[limit]=20",
    "prev": null,
    "next": null
  }
}

Parameterization

The aggregation pipeline allows parameterization where each individual API request can set different parameters. An aggregate must contain parameters attribute which is an object containing all parameters referenced in the aggregation pipeline. These are the default parameters. API request can override all or some parameters using query parameter parameters[<AGT_TYPE>] where value is an stringified object containing parameters. The aggregation pipeline can reference parameter using path expression $$parameters.<PARAMETER_PATH>.

Test aggregate agt.writer-latest-articles contains parameters attribute which introduces parameter articleCount with the default value of 5:

"parameters": {
   "articleCount": 5
}

In the aggregation pipeline parameter articleCount is referenced as a second argument to operator $slice:

"$slice": [ "$articles", "$$parameters.articleCount" ]

To get AGT documents based on parameter articleCount with the value 2, query parameter parameters[agt.writer-latest-articles]={ “articleCount”: 2 } can be used. The complete API request with URL encoded query parameter is:

curl --globoff -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET 'https://api.jazer.io/aggregates/agt.writer-article-overview?parameters[agt.writer-latest-articles]=%7B+%22articleCount%22%3A+2+%7D'

The response is:

{
  "meta": {
    "count": 2
  },
  "data": [
    {
      "type": "agt.writer-latest-articles",
      "id": "5cdde75e2c387e2423a0f389",
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde75e2c387e2423a0f389"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/author"
          }
        },
        "articles": {
          "data": [
            {
              "type": "news.article",
              "id": "5cddeaf62c387e2423a0f3b8"
            },
            {
              "type": "news.article",
              "id": "5cddeada2c387e2423a0f3b4"
            }
          ],
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/relationships/articles",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389/articles"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde75e2c387e2423a0f389"
      }
    },
    {
      "type": "agt.writer-latest-articles",
      "id": "5cdde73a2c387e2423a0f385",
      "relationships": {
        "author": {
          "data": {
            "type": "writer",
            "id": "5cdde73a2c387e2423a0f385"
          },
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/relationships/author",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/author"
          }
        },
        "articles": {
          "data": [
            {
              "type": "news.article",
              "id": "5cddeb242c387e2423a0f3bc"
            },
            {
              "type": "news.article",
              "id": "5cdde8e32c387e2423a0f397"
            }
          ],
          "links": {
            "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/relationships/articles",
            "related": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385/articles"
          }
        }
      },
      "links": {
        "self": "https://api.jazer.io/aggregates/agt.writer-latest-articles/5cdde73a2c387e2423a0f385"
      }
    }
  ],
  "links": {
    "first": "https://api.jazer.io/aggregates/agt.writer-latest-articles?parameters%5Bagt.writer-latest-articles%5D=%7B%20%22articleCount%22:%202%20%7D&page[offset]=0&page[limit]=20",
    "last": "https://api.jazer.io/aggregates/agt.writer-latest-articles?parameters%5Bagt.writer-latest-articles%5D=%7B%20%22articleCount%22:%202%20%7D&page[offset]=0&page[limit]=20",
    "prev": null,
    "next": null
  }
}

Conditional get

Successful AGT search API request will return a response with an ETag header. Repeating the same request with an additional header If-None-Match with the value of an ETag header from the previous response can have two outcomes. The server can return 200 OK and the whole body if primary documents or any of the included documents have changed or 304 Not Modified without the body when there have been no changes to the AGT documents since the last request, i.e. given ETag is still valid.

Example API request searches for AGT documents of type agt.writer-article-overview:

curl -i -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/aggregates/agt.writer-article-overview

The response will be 200 OK with the body containing agt.writer-article-overview documents. Response headers will contain an ETag. Repeat the same API request with an additional header If-None-Match with the value of an ETag header returned from this response:

curl -i -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-H 'If-None-Match: <ETAG_VALUE>' \
-X GET https://api.jazer.io/aggregates/agt.writer-article-overview

The response will be 304 Not Modified if in the meantime new agt.writer-article-overview documents have not been created or existing modified/removed.

Note

Web browsers support local caching using an ETag automatically.