Graph Relationships

Today marks an important milestone for Orchestrate.

Our remarkable little NoSQL database-in-the-cloud already provides a rich data model - a full-featured JSON key-value store, with Items organized into named Collections, a time-series database of Events related to those items, and a graph database of item-to-item Relationships. On top of all that, our API offers exhaustive indexing over every field in your JSON (no schemas required) and a powerful Search API for executing complex queries and aggregations.

Earlier this year, we upgraded our search technology and made it available not just for key-value Items, but also for the Events in the time-series database.

Today, we're doing the same thing for our graph database. Every graph Relationship can (optionally) store a JSON body, and you can use the Search API to find and sort Relationships based on their JSON data, as well as their path metadata.

With these changes, you can finally use the same Search API everywhere: for all the Items, Events, and Relationships in your entire Application. We've even made it possible to search all three kinds of data simultaneously (and across collection boundaries too), creating a truly unified experience for operating over all your Orchestrate data.

Multi-Kind Search

An important part of this new unified Search API is the ability to retrieve any object in your database.

By default, the Search API only returns key-value Items in its results. But now you can override this default behavior by including a clause in your query matching the @path.kind field against any of the three kinds of data: item, event, and relationship. For example, to match only Relationships, you'd include this clause in your query:

@path.kind:relationship

But to match against Items and Relationships simultaneously, you'd query like this:

@path.kind:(item relationship)

And to query for all three kinds, you'd query like this:

@path.kind:*

Cross-Collection Search

Traditionally, Orchestrate has only offered the Search API within the context of an individual Collection. For example, searching on a users Collection would never return results from the products Collection.

But since Relationships in our graph database define connections between the key-value Items in your Application - and since those two Items can exist in entirely different Collections - our new universal Search API had to support cross-collection queries.

With our latest API, you can search all your Collections simultaneously, by sending a request to the root API endpoint:

curl -i "https://api.orchestrate.io/v0?query=$query&limit=$limit&offset=$offset"

By contrast, our previous API only supported searching within the context of a specific Collection, accepting search requests only at the Collection API endpoint:

curl -i "https://api.orchestrate.io/v0/my-collection?query=$query&limit=$limit&offset=$offset"

When you search for Items and Events across Collections, you can use a new @path.collection meta-field to filter your results according to the collections that contain them:

@path.collection:(`users` OR `products`)

Searching for Relationships

With the introduction of graph Relationships into the Search API, we're adding five new path-meta fields that you can use in your queries:

@path.source.collection
@path.source.key
@path.destination.collection
@path.destination.key
@path.relation

Much like the new @path.collection field gives you the ability to search Items and Events by collection, the new @path.source.collection and @path.destination.collection fields allow you to search graph Relationships according to the collections which contain their endpoints.

For example, you could find all relationships between items in the users and products collections using a query like this:

@path.source.collection:`users`
AND
@path.destination.collection:`products`

You can further refine the query by filtering against the name of the relation in this relationship. For example, if you only wanted to find the relationships where a user added a product to their list of favorites, or to their shopping cart, we might use a query like this:

@path.source.collection:`users`
AND
@path.destination.collection:`products`
AND
@path.relation:(`favorite` OR `cart`)

You could further limit these results to only the relationships belonging to a particular source or destination key. For example, you might search for all users who interacted with a particular item like this:

@path.source.collection:`users`
AND
@path.destination.collection:`products`
AND
@path.destination.key:`fancy-coffee-pot`
AND
@path.relation:(`favorite` OR `cart`)

And of course, you can include clauses against the actual JSON of the graph Relationship itself. For example, if our relationship objects contained a created timestamp field, then we could further filter our results to include only those created in the month of October using a query like this:

@path.source.collection:`users`
AND
@path.destination.collection:`products`
AND
@path.destination.key:`fancy-coffee-pot`
AND
@path.relation:(`favorite` OR `cart`)
AND
value.created:[2015-10-01 TO 2015-11-01]

I know, right?

It's pretty great.

Now that we've completed this unification of our Search API, you can easily search all three kinds of objects in the Orchestrate data model - Items, Events, and Relationships - across all the Collections in your Application.

It's never been easier to build something incredible. We can't wait to see what you create.