---
title:  Continuous Queries
---

<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

The C++ and .NET clients can initiate queries that run on the <%=vars.product_name%> cache server
and notify the client when the query results have changed.  For details on the server-side setup for
continuous queries, see [How Continuous Querying Works](<%=vars.serverman%>/developing/continuous_querying/how_continuous_querying_works.html) 
in the *<%=vars.product_name%> User Guide*.

## <a id="cq_main_features" ></a>Continuous Query Basics

Continuous querying provides the following features:

- **Standard <%=vars.product_name%> native client query syntax and semantics**. Continuous queries are expressed in the same language used for other native client queries. See [Remote Queries](remote-queries.html).

- **Standard <%=vars.product_name%> events-based management of CQ events**. The event handling used
to process CQ events is based on the standard <%=vars.product_name%> event handling framework. 

- **Complete integration with the client/server architecture**. CQ functionality uses existing
server-to-client messaging mechanisms to send events. All tuning of your server-to-client
messaging also tunes the messaging of your CQ events. If your system is configured for high
availability then your CQs are highly available, with seamless failover provided in case of
server failure (see [Highly Available Client/Server Event Messaging](<%=vars.serverman%>/developing/events/ha_event_messaging_whats_next.html)). 
If your clients are durable, you can also define any of your CQs as durable (see [Implementing Durable Client/Server Messaging](<%=vars.serverman%>/developing/events/implementing_durable_client_server_messaging.html)).

- **Interest criteria based on data values**. Continuous queries are run against the region's entry values. 
Compare this to register interest by reviewing [Registering Interest for Entries](regions/registering-interest-for-entries.html).

- **Active query execution**. Once initialized, the queries operate on new events. Events that change the query result are sent to the client immediately.

**Note:** Because floating point numbers can not reliably be compared for equality, do not use
floating point values as keys or key components when constructing a query.

## <a id="cq_api"></a>Typical Continuous Query Lifecycle

1.  The client creates the CQ. This sets up everything for running the query and provides the client with a `CqQuery` object, but does not execute the CQ. At this point, the query is in a `STOPPED `state, ready to be closed or run.
2.  The client initiates the CQ with an API call to one of the `CqQuery execute*` methods. This puts the query into a `RUNNING` state on the client and on the server.  The server remotely evaluates the query string, and optionally returns the results to the client. `CqQuery execute*` methods include:
  - `CqQuery.execute()` 
  - `CqQuery.executeWithInitialResults()`

1.  A CQ Listener waits for events. When it receives events, it takes action accordingly with the data in the CqEvent.
3.  The CQ is closed by a client call to `CqQuery.close`. This de-allocates all resources in use for the CQ on the client and server. At this point, the cycle could begin again with the creation of a new `CqQuery` instance.

## <a id="ExecutingACQ"></a>Executing a Continuous Query from the Client

The essential steps to create and execute a continuous query are:

1.  Create an instance of the `QueryService` class. If you are using the pool API (recommended), you should obtain the `QueryService` from the pool.
1.  Define a CQ Listener (a `CqListener`) to field events sent from the server.
1.  Use one of the `CqQuery execute*` methods to submit the query string to the cache server.
1.  The server remotely evaluates the query string, then monitors those results and notifies the client if they change.
1.  The client listens for changes that match the query predicate.
1.  Iterate through the returned objects.
1.  When finished, close down the continuous query.

### <a id="CppCQExample"></a>C++ Continuous Query Example

These C++ code excerpts are from the `examples/cpp/continuousquery` example included in your client
distribution. See the example for full context.

Following the steps listed above,

1. Create a query service:

    ```
    auto queryService = pool->getQueryService();
    ```

1. Define a CqListener:

    ```
    class MyCqListener : public CqListener {
    ```

1. Create an instance of your CqListener and insert it into a CQ attributes object:

    ```
    CqAttributesFactory cqFactory;

    auto cqListener = std::make_shared<MyCqListener>();

    cqFactory.addCqListener(cqListener);
    auto cqAttributes = cqFactory.create();
    ```

1. Create a Continuous Query using the query service and the CQ attributes:

    ```
      auto query = queryService->newCq(
	  "MyCq", "SELECT * FROM /custom_orders c WHERE c.quantity > 30",
	  cqAttributes);
    ```

1. Execute the query:

    ```
    query->execute();
    ```

1. Wait for events and do something with them.

    ```
	/* Excerpt from the CqListener */

	/* Determine Operation Type */
	switch (cqEvent.getQueryOperation()) {
	case CqOperation::OP_TYPE_CREATE:
	  opStr = "CREATE";
	  break;
	case CqOperation::OP_TYPE_UPDATE:
	  opStr = "UPDATE";
	  break;
	case CqOperation::OP_TYPE_DESTROY:
	  opStr = "DESTROY";
	  break;
	default:
	  break;
	}

	...

	/* Take action based on OP Type */

    ```

1. When finished, close up shop.

    ```
    query->execute();

    ... (respond to events as they arrive)

    query->stop();
    query->close();

    cache.close();
    ```
