Examples

This page provides sample searches that you can review to get an idea of what is possible with search within Cloud CMS. Cloud CMS offers full integration to Elastic Search and, in doing so, it gives developers the ability to powerful queries using the Elastic Search DSL (as either JSON or a text-based query string format).

Example: Full-text Search (using JS Driver)

Suppose we want to search for all of the content nodes where the text eddie van halen appears. We can do so by using a full-text search query string, like this:

// assume we have a branch
var branch = ...;

// search!
branch.searchNodes("eddie van halen").each(function() {
    console.log("Found a node with title: " + this.title);
});

Example: DSL Search

All of the content that you put into Cloud CMS is indexed within Elastic Search. This means that all of your JSON properties are available for search purposes using the Elastic Search DSL.

Suppose we have content objects that look similar to this one:

{
    "_type": "my:product",
    "title": "My Product",
    "product": "shirt",
    "price": 10.99,
    "tags": ["shirt", "blue", "popular"],    
    "audience": ["children", "toddlers"],
    "size": "small"
}

That's just an example. Let's imagine we have hundreds or thousands of those content objects in Cloud CMS. Those objects will be available for both query (backed by MongoDB) and search (using Elastic Search). Cloud CMS also provides facilities for performing hybrid query/search combinations across both.

Let's stick to search for the moment.

Suppose we want to find all of the my:product content instances that describe size small shirts. To do so, we want to search for content where:

  • the property product equals shirt
  • the property size equals small
  • the content type is my:product

Here is one way you can write this query within ES:

{
    "query": {
        "bool": {
            "must": [
                { "match": { "product": "shirt" }},
                { "match": { "size":  "small" }},
                { "term": { "__type": "my:product" }}
            ]
        }         
    }
}

In this case, we define a query where the given set of boolean matches MUST satisfy.
We use the Match and Term query DSLs, as defined here:

Elastic Search will run the query and find all matches where product is shirt and size is small. It will then filter to keep only those instances whose content type is my:product.

Note that in Elastic Search, the special __type field is used instead of _type. This is due to a limitation in Elastic Search 6.x that we expect to be resolved in a future version of Elastic Search. For now, please use __type. At a future point, we expect to support _type and will retain support for __type for backward compatibility.

So how do we use this?

From an API perspective, we can post the following:

POST /repositories/{repositoryId}/branches/{branchId}/nodes/search
{
    "search": {
        "query": {
            "bool": {
                "must": [
                    { "match": { "product": "shirt" }},
                    { "match": { "size":  "small" }},
                    { "term": { "__type": "my:product" }}
                ]
            }         
        }    
    }
}

Here is an example of how this is done in code:

// assume we have a branch
var branch = ...;

// search!
branch.searchNodes({
    "search": {
        "query": {
            "bool": {
                "should": [
                    { "match": {"product": "shirt"} },
                    { "match": {"size": "small"} },
                    { "term": { "__type": "my:product" } }
                ]
            }
        }
    }
}).each(function() {
    console.log("Found a node with title: " + this.title);
});

Note that the results come back with full pagination information, allowing you to limit the number of objects that come back and the starting location within the database. Smaller sets perform faster so be mindful of this with your calls.

As with all Cloud CMS queries, you control pagination via request parameters. These include skip and limit. Pagination also allows you specify sort information to control the result set order.

For more information on pagination, please see our documentation on Pagination.

Searching across multiple Content Types

We could also use the Terms query to find matches of multiple types. Suppose we want to run the same query but have it select any content of type my:product OR my:service. We could write:

POST /repositories/{repositoryId}/branches/{branchId}/nodes/search
{
    "search": {
        "query": {
            "bool": {
                "must": [
                    { "match": { "product": "shirt" }},
                    { "match": { "size":  "small" }},
                    { "terms": { "__type": ["my:product", "my:service"] }}
                ]
            }         
        }    
    }
}

Using ES Filters

Elastic Search supports both query elements as well as filter elements. Filters offer some advantages and can be used to achieve the same results.

In the approach above, we structured the query block to use a composite AND across the must elements. That's fine.
However, we could also introduce a filter to only keep results where the content type is either my:product or my:service.

We can do so like this:

POST /repositories/{repositoryId}/branches/{branchId}/nodes/search
{
    "search": {
        "query": {
            "bool": {
                "must": [
                    { "match": { "product": "shirt" }},
                    { "match": { "size":  "small" }}
                ],
                "filter": {
                  "terms": {
                    "__type": [
                      "my:product",
                      "my:service"
                    ]
                  }
                }                
            }         
        }    
    }
}

For details on how to get the most out of the Elastic Search DSL, check out the Elastic Search DSL Query page.