---
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.

**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="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 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](<%=vars.serverman%>/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](<%=vars.serverman%>/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

You must create a `Query` object for each new query. The `Query` interface provides methods for
managing the compilation and execution of queries, and for retrieving an existing query string.

A `Query` is obtained from a `QueryService`, which is obtained from one of two sources:

- To create a `Query` that operates on the <%=vars.product_name%> server, use `Apache::Geode::Client::Pool::GetQueryService()` to instantiate a `QueryService` obtained from a `Pool`.

- To create a `Query` that operates on your application's local cache, use `Apache::Geode::Client::Cache::GetQueryService()` to instantiate a `QueryService` obtained from a `Cache`.

### <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 `Query` instance 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 Framework Query Example

These C# code excerpts are from the `examples\dotnet\remotequery` 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());
    }
    ```


