---
title: Remote 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.
-->

Use the remote query API to query your cached data stored on a cache server. 

## <a id="RemoteQueryBasics"></a>Remote Query Basics

Queries are evaluated and executed on the cache server, and the results are returned to the client.
You can optimize your queries by defining indexes on the cache server.

Querying and indexing operate only on remote cache server contents.

### <a id="QueryLanguage"></a>Query language: OQL
<%=vars.product_name%> provides a SQL-like querying language called OQL that allows you to access data stored in <%=vars.product_name%> regions.
OQL is very similar to SQL, but OQL allows you to query complex objects, object attributes, and methods.

In the context of a query, specify the name of a region by its full path, starting with a slash (`/`).
The query processor performs binary numeric promotion, method invocation conversion, and temporal type conversion.

The query language supports drilling down into nested object structures.
Nested data collections can be explicitly referenced in the FROM clause of a query.

A query execution returns its results as either a `ResultSet` or a `StructSet`. 

Query language features and grammar are described in the <%=vars.product_name%> manual at
[Querying](geodeman/developing/querying_basics/chapter_overview.html).

### <a id="CreatingIndexes"></a>Creating Indexes

Indexes can provide significant performance gains for query execution. You create and maintain indexes on the cache server.
For detailed information about working with indexes configured on a cache server, 
see [Working with Indexes](geodeman/developing/query_index/query_index.html) in the server's documentation.

## <a id="RemoteQueryAPI"></a>Remote Query API

This section gives a general overview of the interfaces and classes that are provided by the query package API.

### <a id="Query"></a>Query

A `Query` is obtained from a `QueryService` method, which is obtained from the cache. The `Query`
interface provides methods for managing the compilation and execution of queries, and for retrieving
an existing query string.

You must create a `Query` object for each new query.

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

The essential steps to create and execute a 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.  Create a `QueryPtr` to a query (C++) or create a query instance (.NET) that is compatible with the OQL specification.
1.  Use the `Query.execute()` method to submit the query string to the cache server. The server
   remotely evaluates the query string and returns the results to the client.
1.  Iterate through the returned objects.

### <a id="DotNetQueryExample"></a>.NET Query Example

These C# code excerpts are from the `examples\dotnet\RemoteQueryCs` example included in your client
distribution. See the example for full context.

Following the steps listed above,

  1. Obtain a `QueryService` object from the connection pool:

    ```
    var queryService = pool.GetQueryService();
    ```

  1. Create a `Query` object by calling `QueryService.NewQuery()`, specifying your OQL query as a string parameter:

    ```
    var query = queryService.NewQuery<Order>("SELECT * FROM /custom_orders WHERE quantity > 30");
    ```

  1. Execute the query. Collect the query output, returned as either a `ResultSet` or a `StructSet`, and iterate through the results:

    ```
    var queryResults = query.Execute();

    foreach (Order value in queryResults)
    {
      Console.WriteLine(value.ToString());
    }
    ```

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

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

Following the steps listed above,

  1. Obtain pointer to a `QueryService` object from the connection pool:

    ```
    std::shared_ptr<QueryService> queryService = nullptr;
    queryService = pool->getQueryService();
    ```

  1. Create a pointer to a `Query` object by calling `QueryService.newQuery()`, specifying your OQL query as a string parameter:

    ```
    auto query = queryService->newQuery("SELECT * FROM /custom_orders WHERE quantity > 30");    
    ```

  1. Execute the query. Collect the query output, returned as either a `ResultSet` or a `StructSet`, and iterate through the results:

    ```
    auto queryResults = query->execute();

    for (auto&& value : *queryResults) {
      auto&& order = std::dynamic_pointer_cast<Order>(value);
      std::cout << order->toString() << std::endl;
    }
    ```

