geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kmil...@apache.org
Subject [30/76] [abbrv] [partial] incubator-geode git commit: GEODE-1952 Consolidated docs under a single geode-docs directory
Date Wed, 12 Oct 2016 17:11:50 GMT
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_additional/case_sensitivity.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_additional/case_sensitivity.html.md.erb b/geode-docs/developing/query_additional/case_sensitivity.html.md.erb
new file mode 100644
index 0000000..2d49259
--- /dev/null
+++ b/geode-docs/developing/query_additional/case_sensitivity.html.md.erb
@@ -0,0 +1,19 @@
+---
+title:  Case Sensitivity
+---
+
+Query language keywords such as SELECT, NULL, DATE, and <TRACE> are case-insensitive. Identifiers such as attribute names, method names, and path expressions are case-sensitive.
+
+In terms of query string and region entry matching, if you want to perform a case-insensitive search on a particular field, you can use the Java String class `toUpperCase` and `toLowerCase` methods in your query. For example:
+
+``` pre
+SELECT entry.value FROM /exampleRegion.entries entry WHERE entry.value.toUpperCase LIKE '%BAR%'
+```
+
+or
+
+``` pre
+SELECT * FROM /exampleRegion WHERE foo.toLowerCase LIKE '%bar%'
+```
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_additional/literals.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_additional/literals.html.md.erb b/geode-docs/developing/query_additional/literals.html.md.erb
new file mode 100644
index 0000000..37fcc0f
--- /dev/null
+++ b/geode-docs/developing/query_additional/literals.html.md.erb
@@ -0,0 +1,65 @@
+---
+title:  Supported Literals
+---
+
+## <a id="literals__section_BA2D0AC444EB45088F00D9E2C8A1DD06" class="no-quick-link"></a>Comparing Values With java.util.Date
+
+Geode supports the following literal types:
+
+<dt>**boolean**</dt>
+<dd>A `boolean` value, either TRUE or FALSE</dd>
+<dt>**int** and **long**</dt>
+<dd>An integer literal is of type `long` if has a suffix of the ASCII letter L. Otherwise it is of type `int`.</dd>
+<dt>**floating point**</dt>
+<dd>A floating-point literal is of type `float` if it has a suffix of an ASCII letter `F`. Otherwise its type is `double`. Optionally, it can have a suffix of an ASCII letter `D`. A double or floating point literal can optionally include an exponent suffix of `E` or `e`, followed by a signed or unsigned number.</dd>
+
+<dt>**string**</dt>
+<dd>String literals are delimited by single quotation marks. Embedded single-quotation marks are doubled. For example, the character string `'Hello'` evaluates to the value `Hello`, while the character string `'He said, ''Hello'''` evaluates to `He said, 'Hello'`. Embedded newlines are kept as part of the string literal.</dd>
+<dt>**char**</dt>
+<dd>A literal is of type char if it is a string literal prefixed by the keyword `CHAR`, otherwise it is of type `string`. The `CHAR` literal for the single-quotation mark character is `CHAR` `''''` (four single quotation marks).</dd>
+<dt>**date**</dt>
+<dd>A `java.sql.Date` object that uses the JDBC format prefixed with the DATE keyword: `DATE yyyy-mm-dd`. In the `Date`, `yyyy` represents the year, `mm` represents the month, and `dd` represents the day. The year must be represented by four digits; a two-digit shorthand for the year is not allowed.</dd>
+<dt>**time**</dt>
+<dd>A `java.sql.Time` object that uses the JDBC format (based on a 24-hour clock) prefixed with the TIME keyword: `TIME hh:mm:ss`. In the `Time`, `hh` represents the hours, `mm` represents the minutes, and `ss` represents the seconds.</dd>
+<dt>**timestamp**</dt>
+<dd>A `java.sql.Timestamp` object that uses the JDBC format with a TIMESTAMP prefix: `TIMESTAMP yyyy-mm-dd hh:mm:ss.fffffffff` In the `Timestamp`, `yyyy-mm-dd` represents the `date`, `hh:mm:ss` represents the `time`, and `fffffffff` represents the fractional seconds (up to nine digits).</dd>
+<dt>**NIL**</dt>
+<dd>Equivalent alternative of `NULL`.</dd>
+<dt>**NULL**</dt>
+<dd>The same as `null` in Java.</dd>
+<dt>**UNDEFINED**</dt>
+<dd>A special literal that is a valid value for any data type. An `UNDEFINED` value is the result of accessing an attribute of a null-valued attribute. Note that if you access an attribute that has an explicit value of null, then it is not undefined. For example if a query accesses the attribute address.city and address is null, the result is undefined. If the query accesses address, then the result is not undefined, it is `NULL`.</dd>
+
+You can compare temporal literal values `DATE`, `TIME`, and `TIMESTAMP` with `java.util.Date` values. There is no literal for `java.util.Date` in the query language.
+
+## <a id="literals__section_9EE6CFC410D2409188EDEAA43AC85851" class="no-quick-link"></a>Type Conversion
+
+The Geode query processor performs implicit type conversions and promotions under certain cases in order to evaluate expressions that contain different types. The query processor performs binary numeric promotion, method invocation conversion, and temporal type conversion.
+
+## <a id="literals__section_F5A3FC509FD04E09B5468BA94B814701" class="no-quick-link"></a>Binary Numeric Promotion
+
+The query processor performs binary numeric promotion on the operands of the following operators:
+
+-   Comparison operators &lt;, &lt;=, &gt;, and &gt;=
+-   Equality operators = and &lt;&gt;
+-   Binary numeric promotion widens the operands in a numeric expression to the widest representation used by any of the operands. In each expression, the query processor applies the following rules in the prescribed order until a conversion is made:
+    1.  If either operand is of type double, the other is converted to double
+    2.  If either operand is of type float, the other is converted to float
+    3.  If either operand is of type long, the other is converted to long
+    4.  Both operands are converted to type int char
+
+## <a id="literals__section_BA277AC4A9B34C93A5291ECC1FDC11C7" class="no-quick-link"></a>Method Invocation Conversion
+
+Method invocation conversion in the query language follows the same rules as Java method invocation conversion, except that the query language uses runtime types instead of compile time types, and handles null arguments differently than in Java. One aspect of using runtime types is that an argument with a null value has no typing information, and so can be matched with any type parameter. When a null argument is used, if the query processor cannot determine the proper method to invoke based on the non-null arguments, it throws an AmbiguousNameException
+
+## <a id="literals__section_0A1A6EFE98A24538B651373B1C6ED8C0" class="no-quick-link"></a>Temporal Type Conversion
+
+The temporal types that the query language supports include the Java types java.util.Date , java.sql.Date , java.sql.Time , and java.sql.Timestamp , which are all treated the same and can be compared and used in indexes. When compared with each other, these types are all treated as nanosecond quantities.
+
+## <a id="literals__section_73255A4630C94D04B461B1480AAF2F66" class="no-quick-link"></a>Enum Conversion
+
+Enums are not automatically converted. To use Enum values in query, you must use the toString method of the enum object or use a query bind parameter. See [Enum Objects](../query_select/the_where_clause.html#the_where_clause__section_59E7D64746AE495D942F2F09EF7DB9B5) for more information.
+
+## <a id="literals__section_CB624C143A2743C5ADC6F95C962F176B" class="no-quick-link"></a>Query Evaulation of Float.NaN and Double.NaN
+
+Float.NaN and Double.NaN are not evaluated as primitives; instead, they are compared in the same manner used as the JDK methods Float.compareTo and Double.compareTo. See [Double.NaN and Float.NaN Comparisons](../query_select/the_where_clause.html#the_where_clause__section_E7206D045BEC4F67A8D2B793922BF213) for more information.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_additional/operators.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_additional/operators.html.md.erb b/geode-docs/developing/query_additional/operators.html.md.erb
new file mode 100644
index 0000000..b05d5d3
--- /dev/null
+++ b/geode-docs/developing/query_additional/operators.html.md.erb
@@ -0,0 +1,40 @@
+---
+title:  Operators
+---
+
+Geode supports comparison, logical, unary, map, index, dot, and right arrow operators.
+
+## <a id="operators__section_A3FB372F85D840D7A49CB95BD7FCA7C6" class="no-quick-link"></a>Comparison Operators
+
+Comparison operators compare two values and return the results, either TRUE or FALSE.
+
+The following are supported comparison operators:
+
+|                       |                                |
+|-----------------------|--------------------------------|
+| = equal to            | &lt; less than                 |
+| &lt;&gt; not equal to | &lt;= less than or equal to    |
+| != not equal to       | &gt; greater than              |
+|                       | &gt;= greater than or equal to |
+
+The equal and not equal operators have lower precedence than the other comparison operators. They can be used with null. To perform equality or inequality comparisons with UNDEFINED, use the IS\_DEFINED and IS\_UNDEFINED preset query functions instead of these comparison operators.
+
+## <a id="operators__section_6A85A9DDA47E47009FDE1CC38D7BA66C" class="no-quick-link"></a>Logical Operators
+
+The logical operators AND and OR allow you to create more complex expressions by combining expressions to produce a boolean result. When you combine two conditional expressions using the AND operator, both conditions must evaluate to true for the entire expression to be true. When you combine two conditional expressions using the OR operator, the expression evaluates to true if either one or both of the conditions are true. You can create complex expressions by combining multiple simple conditional expressions with AND and OR operators. When expressions use AND and OR operators, AND has higher precedence than OR.
+
+## <a id="operators__section_A970AE75B0D24E0B9E1B61BE2D9842D8" class="no-quick-link"></a>Unary Operators
+
+Unary operators operate on a single value or expression, and have lower precedence than comparison operators in expressions. Geode supports the unary operator NOT. NOT is the negation operator, which changes the value of the operand to its opposite. So if an expression evaluates to TRUE, NOT changes it to FALSE. The operand must be a boolean.
+
+## <a id="operators__section_E78FB4FB3703471C8186A0E26D25F01F" class="no-quick-link"></a>Map and Index Operators
+
+Map and index operators access elements in key/value collections (such as maps and regions) and ordered collections (such as arrays, lists, and `String`s). The operator is represented by a set of square brackets (`[ ]`) immediately following the name of the collection. The mapping or indexing specification is provided inside these brackets.
+
+Array, list, and `String` elements are accessed using an index value. Indexing starts from zero for the first element, 1 for the second element and so on. If `myList` is an array, list, or String and `index` is an expression that evaluates to a non-negative integer, then `myList[index]` represents the (`index + 1`)th element of `myList`. The elements of a `String` are the list of characters that make up the string.
+
+Map and region values are accessed by key using the same syntax. The key can be any `Object`. For a `Region`, the map operator performs a non-distributed `get` in the local cache only - with no use of `netSearch`. So `myRegion[keyExpression]` is the equivalent of `myRegion.getEntry(keyExpression).getValue`.
+
+## <a id="operators__section_6C0BB787B2324B85AA02AA19D4822A83" class="no-quick-link"></a>Dot, Right Arrow, and Forward Slash Operators
+
+The dot operator (`.`) separates attribute names in a path expression, and specifies the navigation through object attributes. An alternate equivalent to the dot is the right arrow, (`->`). The forward slash is used to separate region names when navigating into subregions.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_additional/order_by_on_partitioned_regions.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_additional/order_by_on_partitioned_regions.html.md.erb b/geode-docs/developing/query_additional/order_by_on_partitioned_regions.html.md.erb
new file mode 100644
index 0000000..4d52a88
--- /dev/null
+++ b/geode-docs/developing/query_additional/order_by_on_partitioned_regions.html.md.erb
@@ -0,0 +1,18 @@
+---
+title:  Using ORDER BY on Partitioned Regions
+---
+
+To execute a query with an ORDER BY clause on a partitioned region, the fields specified in the ORDER BY clause must be part of the projection list.
+
+When an ORDER BY clause is used with a partition region query, the query is executed separately on each region host, the local query coordinator, and all remote members. The results are all gathered by the query coordinator. The cumulative result set is built by applying ORDER BY on the gathered results. If the LIMIT clause is also used in the query, ORDER BY and LIMIT are applied on each node before each node’s results are returned to the coordinator. Then the clauses are applied to the cumulative result set to get the final result set, which is returned to the calling application.
+
+**Example:**
+
+``` pre
+// This query works because p.status is part of projection list
+select distinct p.ID, p.status from /region p where p.ID > 5 order by p.status
+// This query works providing status is part of the value indicated by *
+select distinct * from /region where ID > 5 order by status 
+```
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_additional/partitioned_region_key_or_field_value.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_additional/partitioned_region_key_or_field_value.html.md.erb b/geode-docs/developing/query_additional/partitioned_region_key_or_field_value.html.md.erb
new file mode 100644
index 0000000..f97c011
--- /dev/null
+++ b/geode-docs/developing/query_additional/partitioned_region_key_or_field_value.html.md.erb
@@ -0,0 +1,66 @@
+---
+title:  Optimizing Queries on Data Partitioned by a Key or Field Value
+---
+
+You can improve query performance on data that is partitioned by key or a field value by creating a key index and then executing the query using the `FunctionService` with the key or field value used as filter.
+
+The following is an example how to optimize a query that will be run on data partitioned by region key value. In the following example, data is partitioned by the "orderId" field.
+
+1.  Create a key index on the orderId field. See [Creating Key Indexes](../query_index/creating_key_indexes.html#concept_09E29507AF0D42CF81D261B030D0B7C8) for more details.
+2.  Execute the query using the function service with orderId provided as the filter to the function context. For example:
+
+    ``` pre
+    /**
+     * Execute MyFunction for query on data partitioned by orderId key
+     *
+     */
+    public class TestFunctionQuery {
+
+      public static void main(String[] args) {
+
+        Set filter =  new HashSet();
+        ResultCollector rcollector = null;
+
+        //Filter data based on orderId  = '12345'
+        filter.add(12345);
+
+        //Query to get all orders that match ID 12345 and amount > 1000
+        String qStr = "SELECT * FROM /Orders WHERE orderId = '12345' AND amount > 1000";
+
+        try {
+          Function func = new MyFunction("testFunction");
+
+          Region region = CacheFactory.getAnyInstance().getRegion("myPartitionRegion");
+
+          //Function will be routed to one node containing the bucket
+          //for ID=1 and query will execute on that bucket.
+          rcollector = FunctionService
+              .onRegion(region)
+              .withArgs(qStr)
+              .withFilter(filter)
+              .execute(func);
+
+          Object result = rcollector.getResult();
+
+          //Results from one or multiple nodes.
+          ArrayList resultList = (ArrayList)result;
+
+          List queryResults = new ArrayList();
+
+          if (resultList.size()!=0) {
+            for (Object obj: resultList) {
+              if (obj != null) {
+                queryResults.addAll((ArrayList)obj);
+              }
+            }
+          }
+          printResults(queryResults);
+
+        } catch (FunctionException ex) {
+            getLogger().info(ex);
+        }
+      }
+    }
+    ```
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_additional/partitioned_region_query_restrictions.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_additional/partitioned_region_query_restrictions.html.md.erb b/geode-docs/developing/query_additional/partitioned_region_query_restrictions.html.md.erb
new file mode 100644
index 0000000..429081e
--- /dev/null
+++ b/geode-docs/developing/query_additional/partitioned_region_query_restrictions.html.md.erb
@@ -0,0 +1,33 @@
+---
+title:  Partitioned Region Query Restrictions
+---
+
+## <a id="concept_5353476380D44CC1A7F586E5AE1CE7E8__section_16875A7EA07D42C08FB194F4A854360D" class="no-quick-link"></a>Query Restrictions in Partitioned Regions
+
+Partitioned region queries function the same as non-partitioned region queries, except for the restrictions listed in this section. Partitioned region queries that do not follow these guidelines generate an `UnsupportedOperationException`.
+
+-   Join queries between partitioned region and between partitioned regions and replicated regions are supported through the function service only. Join queries partitioned regions are not supported through the client server API.
+-   You can run join queries on partitioned regions and on partitioned regions and replicated regions only if they are co-located. Equi-join queries are supported only on partitioned regions that are co-located and where the co-located columns are indicated in the WHERE clause of the query. In the case of multi-column partitioning, there should also be an AND clause in the WHERE specification. See [Colocate Data from Different Partitioned Regions](../partitioned_regions/colocating_partitioned_region_data.html#colocating_partitioned_region_data) for more information on partitioned region co-location.
+-   Equi-join queries are allowed between partitioned regions and between partitioned regions and local replicated regions as long as the local replicated region also exists on all partitioned region nodes. To perform a join query on a partitioned region and another region (partitioned or not), you need to use the `query.execute` method and supply it with a function execution context. See [Performing an Equi-Join Query on Partitioned Regions](../partitioned_regions/join_query_partitioned_regions.html#concept_B930D276F49541F282A2CFE639F107DD) for an example.
+-   The query must be just a SELECT expression (as opposed to arbitrary OQL expressions), preceded by zero or more IMPORT statements. For example, this query is not allowed because it is not just a SELECT expression:
+
+    ``` pre
+    // NOT VALID for partitioned regions
+    (SELECT DISTINCT *FROM /prRgn WHERE attribute > 10).size
+    ```
+
+    This query is allowed:
+
+    ``` pre
+    // VALID for partitioned regions
+    SELECT DISTINCT *FROM /prRgn WHERE attribute > 10
+    ```
+
+-   The SELECT expression itself can be arbitrarily complex, including nested SELECT expressions, as long as only one partitioned region is referenced.
+-   The partitioned region reference can only be in the first FROM clause iterator. Additional FROM clause iterators are allowed if they do not reference any regions (such as drilling down into the values in the partitioned region).
+-   The first FROM clause iterator must contain only one reference to the partitioned region (the reference can be a parameter, such as $1).
+-   The first FROM clause iterator cannot contain a subquery, but subqueries are allowed in additional FROM clause iterators.
+-   You can use ORDER BY on partitioned region queries, but the fields that are specified in the ORDER BY clause must be part of the projection list.
+-   If a partition region (or a bucket) being queried has been destroyed, the query is reattempted on the new primary for the destroyed bucket (if it exists). After certain number of attempts, a QueryException is thrown if all buckets (calculated at the startup of the query) cannot be queried.
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_additional/query_debugging.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_additional/query_debugging.html.md.erb b/geode-docs/developing/query_additional/query_debugging.html.md.erb
new file mode 100644
index 0000000..b39cf08
--- /dev/null
+++ b/geode-docs/developing/query_additional/query_debugging.html.md.erb
@@ -0,0 +1,87 @@
+---
+title:  Query Debugging
+---
+
+You can debug a specific query at the query level by adding the `<trace>` keyword before the query string that you want to debug.
+
+Here is an example:
+
+``` pre
+<trace> select * from /exampleRegion
+```
+
+You can also write:
+
+``` pre
+<TRACE> select * from /exampleRegion
+```
+
+When the query is executed, Geode will log a message in `$GEMFIRE_DIR/system.log` with the following information:
+
+``` pre
+[info 2011/08/29 11:24:35.472 PDT CqServer <main> tid=0x1] Query Executed in 9.619656 ms; rowCount = 99; indexesUsed(0) "select *  from /exampleRegion" 
+```
+
+If you want to enable debugging for all queries, you can enable query execution logging by setting a System property on the command line during start-up:
+
+``` pre
+gfsh>start server --name=server_name -–J=-Dgemfire.Query.VERBOSE=true
+```
+
+Or you can set the property programmatically:
+
+``` pre
+System.setProperty("gemfire.Query.VERBOSE","true");
+```
+
+As an example, let us say you have an EmployeeRegion that that contains Employee objects as values and the objects have public fields in them like ID and status.
+
+``` pre
+Employee.java
+Class Employee {
+ public int ID;
+ public String status;
+ - - - - - -
+ - - - - - -
+}
+```
+
+In addition, you have created the following indexes for the region:
+
+``` pre
+<index name="sampleIndex-1">
+<functional from-clause="/test " expression="ID"/>
+</index>
+<index name="sampleIndex-2">
+<functional from-clause="/test " expression="status"/>
+</index>
+```
+
+After you have set `gemfire.Query.VERBOSE` to "true", you could see the following debug messages in the logs after running queries on the EmployeeRegion or its indexes:
+
+-   If indexes are not used in the query execution, you would see a debug message like this:
+
+    ``` pre
+    [info 2011/08/29 11:24:35.472 PDT CqServer <main> tid=0x1] Query Executed in 9.619656 ms; rowCount = 99; indexesUsed(0) "select * from /test k where ID > 0 and status='active'"
+    ```
+
+-   When single index is used in query execution, you might see a debug message like this:
+
+    ``` pre
+    [info 2011/08/29 11:24:35.472 PDT CqServer <main> tid=0x1] Query Executed in 101.43499 ms; rowCount = 199; indexesUsed(1):sampleIndex-1(Results: 199) "select count *   from /test k where ID > 0"
+    ```
+
+-   When multiple indexes are used by a query, you might see a debug message like this:
+
+    ``` pre
+    [info 2011/08/29 11:24:35.472 PDT CqServer <main> tid=0x1] Query Executed in 79.43847 ms; rowCount = 199; indexesUsed(2):sampleIndex-2(Results: 100),sampleIndex-1(Results: 199) "select * from /test k where ID > 0 OR status='active'"
+    ```
+
+In above log messages, the following information is provided:
+
+-   "rowCount" represents ResultSet size for the query.
+-   "indexesUsed(\\n) " shows n indexes were used for finding the results of the query.
+-   Each index name and its corresponding results are reported respectively.
+-   The log can be identified with the original query string itself appended in the end.
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_additional/query_language_features.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_additional/query_language_features.html.md.erb b/geode-docs/developing/query_additional/query_language_features.html.md.erb
new file mode 100644
index 0000000..eea7cc0
--- /dev/null
+++ b/geode-docs/developing/query_additional/query_language_features.html.md.erb
@@ -0,0 +1,24 @@
+---
+title:  OQL Syntax and Semantics
+---
+
+<a id="concept_5B8BA904DF2A41BEAA057017777D4E90__section_33F0FD791A2448CB812E8397828B33C2"></a>
+This section covers the following querying language features:
+
+-   **[Supported Character Sets](../../developing/querying_basics/supported_character_sets.html)**
+
+-   **[Supported Keywords](../../developing/query_additional/supported_keywords.html)**
+
+-   **[Case Sensitivity](../../developing/query_additional/case_sensitivity.html)**
+
+-   **[Comments in Query Strings](../../developing/querying_basics/comments_in_query_strings.html)**
+
+-   **[Query Language Grammar](../../developing/querying_basics/query_grammar_and_reserved_words.html)**
+
+-   **[Operators](../../developing/query_additional/operators.html)**
+
+-   **[Reserved Words](../../developing/querying_basics/reserved_words.html)**
+
+-   **[Supported Literals](../../developing/query_additional/literals.html)**
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_additional/query_on_a_single_node.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_additional/query_on_a_single_node.html.md.erb b/geode-docs/developing/query_additional/query_on_a_single_node.html.md.erb
new file mode 100644
index 0000000..6b56cb0
--- /dev/null
+++ b/geode-docs/developing/query_additional/query_on_a_single_node.html.md.erb
@@ -0,0 +1,155 @@
+---
+title:  Querying a Partitioned Region on a Single Node
+---
+
+To direct a query to specific partitioned region node, you can execute the query within a function. Use the following steps:
+
+1.  Implement a function which executes a query using RegionFunctionContext.
+
+    ``` pre
+    /**
+     * This function executes a query using its RegionFunctionContext
+     * which provides a filter on data which should be queried.
+     *
+     */
+    public class MyFunction extends FunctionAdapter {
+
+        private final String id;
+
+        @Override
+        public void execute(FunctionContext context) {
+
+          Cache cache = CacheFactory.getAnyInstance();
+          QueryService queryService = cache.getQueryService();
+
+          String qstr = (String) context.getArguments();
+
+          try {
+            Query query = queryService.newQuery(qstr);
+
+            //If function is executed on region, context is RegionFunctionContext
+            RegionFunctionContext rContext = (RegionFunctionContext)context;
+
+            SelectResults results = (SelectResults) query.execute(rContext)
+
+            //Send the results to function caller node.
+            context.getResultSender().sendResult((ArrayList) (results).asList());
+            context.getResultSender().lastResult(null);
+
+          } catch (Exception e) {
+            throw new FunctionException(e);
+          }
+        }
+
+        @Override
+        public boolean hasResult() {
+          return true;
+        }
+
+        @Override
+        public boolean isHA() {
+          return false;
+        }
+
+
+        public MyFunction(String id) {
+          super();
+          this.id = id;
+        }
+
+        @Override
+        public String getId() {
+          return this.id;
+        }
+      }
+    ```
+
+2.  Decide on the data you want to query. Based on this decision, you can use `PartitionResolver` to configure the organization of buckets to be queried in the Partitioned Region.
+
+    For example, let's say that you have defined the PortfolioKey class:
+
+    ``` pre
+    public class PortfolioKey implements DataSerializable {
+      private int id;
+      private long startValidTime;
+      private long endValidTime
+      private long writtenTime
+      
+      public int getId() {
+        return this.id;
+      }
+    ...
+    }
+    ```
+
+    You could use the `MyPartitionResolver` to store all keys with the same ID in the same bucket. This `PartitionResolver` has to be configured at the time of Partition Region creation either declaratively using xml OR using APIs. See [Configuring Partitioned Regions](../partitioned_regions/managing_partitioned_regions.html#configure_partitioned_regions) for more information.
+
+    ``` pre
+    /** This resolver returns the value of the ID field in the key. With this resolver, 
+     * all Portfolios using the same ID are colocated in the same bucket.
+     */
+    public class MyPartitionResolver implements PartitionResolver, Declarable {
+
+       public Serializable getRoutingObject(EntryOperation operation) {
+       return operation.getKey().getId();
+    }
+    ```
+
+3.  Execute the function on a client or any other node by setting the filter in the function call.
+
+    ``` pre
+    /**
+     * Execute MyFunction for query on specified keys.
+     *
+     */
+    public class TestFunctionQuery {
+
+      public static void main(String[] args) {
+
+        ResultCollector rcollector = null;
+        PortfolioKey portfolioKey1 = ...;
+
+        //Filter data based on portfolioKey1 which is the key used in 
+        //region.put(portfolioKey1, portfolio1);
+        Set filter = Collections.singleton(portfolioKey1);
+
+        //Query to get all positions for portfolio ID = 1
+        String qStr = "SELECT positions FROM /myPartitionRegion WHERE ID = 1";
+
+        try {
+          Function func = new MyFunction("testFunction");
+
+          Region region = CacheFactory.getAnyInstance().getRegion("myPartitionRegion");
+
+          //Function will be routed to one node containing the bucket
+          //for ID=1 and query will execute on that bucket.
+          rcollector = FunctionService
+              .onRegion(region)
+              .withArgs(qStr)
+              .withFilter(filter)
+              .execute(func);
+
+          Object result = rcollector.getResult();
+
+          //Results from one or multiple nodes.
+          ArrayList resultList = (ArrayList)result;
+
+          List queryResults = new ArrayList();
+
+          if (resultList.size()!=0) {
+            for (Object obj: resultList) {
+              if (obj != null) {
+                queryResults.addAll((ArrayList)obj);
+              }
+            }
+          }
+          printResults(queryResults);
+
+        } catch (FunctionException ex) {
+            getLogger().info(ex);
+        }
+      }
+    }
+    ```
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_additional/supported_keywords.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_additional/supported_keywords.html.md.erb b/geode-docs/developing/query_additional/supported_keywords.html.md.erb
new file mode 100644
index 0000000..1a257f6
--- /dev/null
+++ b/geode-docs/developing/query_additional/supported_keywords.html.md.erb
@@ -0,0 +1,31 @@
+---
+title:  Supported Keywords
+---
+
+| Query Language Keyword | Description                                                                                                                                                                                                                                                                                                                                         | Example                                                                                                                                                                                                                                                    |
+|------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| AND                    | Logical operator used to create complex expressions by combining two or more expressions to produce a Boolean result. When you combine two conditional expressions using the AND operator, both conditions must evaluate to true for the entire expression to be true.                                                                              | See [Operators](operators.html#operators)                                                                                                                                                                                          |
+| AS                     | Used to provide a label for a path expression so you can refer to the path by the label later.                                                                                                                                                                                                                                                      | See [Aliases and Synonyms](../query_select/the_from_clause.html#the_from_clause__section_AB1734C16DC348479C00FD6829B933AA)                                                                                                         |
+| COUNT                  | Returns the number of results that match the provided criteria.                                                                                                                                                                                                                                                                                     | See [COUNT](../query_select/the_select_statement.html#concept_85AE7D6B1E2941ED8BD2A8310A81753E__section_B2CBA00EB83F463DAF4769D7859C64C8)                                                                                          |
+| DISTINCT               | Restricts the select statement to unique results (eliminates duplicates).                                                                                                                                                                                                                                                                           | See [DISTINCT](../query_select/the_select_statement.html#concept_85AE7D6B1E2941ED8BD2A8310A81753E__section_972EE73A6F3E4427B6A99DB4EDF5860D)                                                                                       |
+| ELEMENT                | Query function. Extracts a single element from a collection or array. This function throws a `FunctionDomainException ` if the argument is not a collection or array with exactly one element.                                                                                                                                                      | See [Preset Query Functions](../query_select/the_select_statement.html#concept_85AE7D6B1E2941ED8BD2A8310A81753E__section_69DCAD624E9640028BC86FD67649DEB2)                                                                         |
+| FROM                   | You can access any object or object attribute that is available in the current scope of the query.                                                                                                                                                                                                                                                  | See [FROM Clause](../query_select/the_from_clause.html#the_from_clause)                                                                                                                                                            |
+| &lt;HINT&gt;           | Keyword that instructs the query engine to prefer certain indexes.                                                                                                                                                                                                                                                                                  | See [Using Query Index Hints](../query_index/query_index_hints.html)                                                             |
+| IMPORT                 | Used to establish the namescope for objects.                                                                                                                                                                                                                                                                                                        | See [IMPORT Statement](../query_select/the_import_statement.html#concept_2E9F15B2FE9041238B54736103396BF7)                                                                                                                         |
+| IN                     | The IN expression is a Boolean indicating whether one expression is present inside a collection of expressions of a compatible type.                                                                                                                                                                                                                | See [IN and SET](../query_select/the_where_clause.html#the_where_clause__section_AC12146509F141378E493078540950C7)                                                                                                                 |
+| IS\_DEFINED            | Query function. Returns TRUE if the expression does not evaluate to UNDEFINED.                                                                                                                                                                                                                                                                      | See [Preset Query Functions](../query_select/the_select_statement.html#concept_85AE7D6B1E2941ED8BD2A8310A81753E__section_69DCAD624E9640028BC86FD67649DEB2)                                                                         |
+| IS\_UNDEFINED          | Query function. Returns TRUE if the expression evaluates to UNDEFINED. In most queries, undefined values are not included in the query results. The IS\_UNDEFINED function allows undefined values to be included, so you can identify element with undefined values.                                                                               | See [Preset Query Functions](../query_select/the_select_statement.html#concept_85AE7D6B1E2941ED8BD2A8310A81753E__section_69DCAD624E9640028BC86FD67649DEB2)                                                                         |
+| LIMIT                  | Limits the number of returned results. If you use the limit keyword, you cannot also run operations on the query result set that perform any kind of summary activities. For example trying to run add or addAll or a SelectResult from a query with a LIMIT clause throws an exception.                                                            | See [LIMIT](../query_select/the_select_statement.html#concept_85AE7D6B1E2941ED8BD2A8310A81753E__section_25D7055B33EC47B19B1B70264B39212F)                                                                                          |
+| LIKE                   | LIKE can be used to mean 'equals to', or if you terminate the string with a wildcard character (`%`), it behaves like 'starts with'. Note that the wildcard can only be used at the end of the comparison string. You can escape the wildcard character to represent the `%` character. You can also use the LIKE predicate if an index is present. | See [LIKE](../query_select/the_where_clause.html#the_where_clause__section_D91E0B06FFF6431490CC0BFA369425AD)                                                                                                                       |
+| NOT                    | The example returns the set of portfolios that have positions. Note that NOT cannot use an index.                                                                                                                                                                                                                                                   | See [Operators](operators.html#operators)                                                                                                                                                                                          |
+| NVL                    | Returns expr2 if expr1 is null. The expressions can be query parameters (bind arguments), path expressions, or literals.                                                                                                                                                                                                                            | See [Preset Query Functions](../query_select/the_select_statement.html#concept_85AE7D6B1E2941ED8BD2A8310A81753E__section_69DCAD624E9640028BC86FD67649DEB2)                                                                         |
+| OR                     | If an expression uses both AND and OR operators, the AND expression has higher precedence than OR.                                                                                                                                                                                                                                                  | See [Operators](operators.html#operators)                                                                                                                                                                                          |
+| ORDER BY               | Allows you to order query results (either in ascending or descending order).                                                                                                                                                                                                                                                                        | See [ORDER BY](../query_select/the_select_statement.html#concept_85AE7D6B1E2941ED8BD2A8310A81753E__section_D9DF0F785CA94EF8B367C3326CC12990)                                                                                       |
+| SELECT                 | Allows you to filter data from the collection of object(s) returned by a WHERE search operation.                                                                                                                                                                                                                                                    | See [SELECT Statement](../query_select/the_select_statement.html#concept_85AE7D6B1E2941ED8BD2A8310A81753E)                                                                                                                         |
+| SET                    | Specifies a collection of values that can be compared to the returned values of query.                                                                                                                                                                                                                                                              | See [IN and SET](../query_select/the_where_clause.html#the_where_clause__section_AC12146509F141378E493078540950C7)                                                                                                                 |
+| &lt;TRACE&gt;          | Enables debugging on the following query string.                                                                                                                                                                                                                                                                                                    | See [Query Debugging](query_debugging.html#concept_2D557E24AAB24044A3DB36B3124F6748) |
+| TO\_DATE               | Returns a Java Data class object. The arguments must be String S with date\_str representing the date and format\_str representing the format used by date\_str. The format\_str you provide is parsed using java.text.SimpleDateFormat.                                                                                                            | See [Preset Query Functions](../query_select/the_select_statement.html#concept_85AE7D6B1E2941ED8BD2A8310A81753E__section_69DCAD624E9640028BC86FD67649DEB2)                                                                         |
+| TYPE                   | Specifying object type in the FROM clause helps the query engine to process the query at optimal speed.                                                                                                                                                                                                                                             | See [Object Typing](../query_select/the_from_clause.html#the_from_clause__section_A5B42CCB7C924949954AEC2DAAD51134)                                                                                                                |
+| WHERE                  | Resolves to a collection of objects. The collection is then available for iteration in the query expressions that follow in the WHERE clause.                                                                                                                                                                                                       | See [WHERE Clause](../query_select/the_where_clause.html#the_where_clause)                                                                                                                                                         |
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_additional/using_query_bind_parameters.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_additional/using_query_bind_parameters.html.md.erb b/geode-docs/developing/query_additional/using_query_bind_parameters.html.md.erb
new file mode 100644
index 0000000..cf9dcea
--- /dev/null
+++ b/geode-docs/developing/query_additional/using_query_bind_parameters.html.md.erb
@@ -0,0 +1,48 @@
+---
+title:  Using Query Bind Parameters
+---
+
+Using query bind parameters in Geode queries is similar to using prepared statements in SQL where parameters can be set during query execution. This allows user to build a query once and execute it multiple times by passing the query conditions during run time.
+
+Query objects are thread-safe.
+
+The use of query bind parameters is now supported in Client-to-Server queries.
+
+The query parameters are identified by a dollar sign, $, followed by a digit that represents the parameter's position in the parameter array passed to the execute method. Counting begins at 1, so $1 references the first bound attribute, $2 the second attribute, and so on.
+
+The Query interface provides an overloaded execute method that accepts parameters inside an Object array. See the [Query.execute](/releases/latest/javadoc/org/apache/geode/cache/query/Query.html) JavaDocs for more details.
+
+The 0th element of the Object array is used for the first query parameter, and so on. If the parameter count or parameter types do not match the query specification, the execute method throws an exception. Specifically, if you pass in the wrong number of parameters, the method call throws a `QueryParameterCountInvalidException`. If a parameter object type is not compatible with what is expected, the method call throws a `TypeMismatchException`.
+
+In the following example, the first parameter, the integer **2**, is bound to the first element in the object array. The second parameter, **active**, is bound to the second element.
+
+## <a id="concept_173E775FE46B47DF9D7D1E40680D34DF__section_7F5A800E2DA643F2B30162EF45DBA390" class="no-quick-link"></a>Sample Code
+
+``` pre
+// specify the query string
+String queryString = "SELECT DISTINCT * FROM /exampleRegion p WHERE p.id = $1 and p.status = $2";
+
+QueryService queryService = cache.getQueryService();
+Query query = queryService.newQuery(queryString);
+
+// set query bind parameters
+Object[] params = new Object[2];
+params[0] = 2;
+params[1] = "active";
+
+// Execute the query locally. It returns the results set.
+SelectResults results = (SelectResults) query.execute(params);
+
+// use the results of the query; this example only looks at the size 
+ int size = results.size();
+```
+
+## <a id="concept_173E775FE46B47DF9D7D1E40680D34DF__section_90B4A0010CDA481581B650AE6D9EBA34" class="no-quick-link"></a>Using Query Bind Parameters in the Path Expression
+
+Additionally the query engine supports the use of query bind parameter in place of a region path. When you specify a bind parameter in the query's FROM clause, the parameter's referenced value must be bound to a collection.
+
+For example, the following query can be used on any collection by passing in the collection as a query parameter value. In this query you could pass in a Region Object for $1, but not the String name of a region.
+
+``` pre
+SELECT DISTINCT * FROM $1 p WHERE p.status = $2
+```

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_index/create_multiple_indexes.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_index/create_multiple_indexes.html.md.erb b/geode-docs/developing/query_index/create_multiple_indexes.html.md.erb
new file mode 100644
index 0000000..a629349
--- /dev/null
+++ b/geode-docs/developing/query_index/create_multiple_indexes.html.md.erb
@@ -0,0 +1,61 @@
+---
+title:  Creating Multiple Indexes at Once
+---
+
+In order to speed and promote efficiency when creating indexes, you can define multiple indexes and then create them all at once.
+
+Defining multiple indexes before creating them speeds up the index creation process by iterating over region entries only once.
+
+You can define multiple indexes of different types at once by specifying the `--type` parameter at definition time.
+
+To define multiple indexes, you can use gfsh or the Java API:
+
+**gfsh example:**
+
+``` pre
+gfsh> define index --name=myIndex1 --expression=exp1 --region=/exampleRegion 
+
+gfsh> define index --name=myIndex2 --expression="c.exp2" --region="/exampleRegion e, e.collection1 c" 
+
+gfsh> define index --name=myIndex3 --expression=exp3 --region=/exampleRegion --type=hash 
+
+gfsh> create defined indexes
+ 
+```
+
+If index creation fails, you may receive an error message in gfsh similar to the following:
+
+``` pre
+gfsh>create defined indexes
+Exception : org.apache.geode.cache.query.RegionNotFoundException , 
+Message : Region ' /r3' not found: from  /r3Occurred on following members
+1. india(s1:17866)<v1>:27809
+```
+
+**Java API example:**
+
+``` pre
+ Cache cache = new CacheFactory().create();
+    QueryService queryService = cache.getQueryService();
+    queryService.defineIndex("name1", "indexExpr1", "regionPath1");
+    queryService.defineIndex("name2", "indexExpr2", "regionPath2");
+    queryService.defineHashIndex("name3", "indexExpr3", "regionPath2");
+    queryService.defineKeyIndex("name4", "indexExpr4", "regionPath2");
+    List<Index> indexes = queryService.createDefinedIndexes();
+```
+
+If one or more index population fails, Geode collect the Exceptions and continues to populate the rest of the indexes. The collected `Exceptions` are stored in a Map of index names and exceptions that can be accessed through `MultiIndexCreationException`.
+
+Index definitions are stored locally on the `gfsh` client. If you want to create a new set of indexes or if one or more of the index creations fail, you might want to clear the definitions stored by using `clear defined indexes`command. The defined indexes can be cleared by using the Java API:
+
+``` pre
+queryService.clearDefinedIndexes();
+```
+
+or gfsh:
+
+``` pre
+gfsh> clear defined indexes
+```
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_index/creating_an_index.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_index/creating_an_index.html.md.erb b/geode-docs/developing/query_index/creating_an_index.html.md.erb
new file mode 100644
index 0000000..8e977a7
--- /dev/null
+++ b/geode-docs/developing/query_index/creating_an_index.html.md.erb
@@ -0,0 +1,94 @@
+---
+title:  Creating, Listing and Removing Indexes
+---
+
+The Geode `QueryService` API provides methods to create, list and remove the index. You can also use `gfsh` command-line interface to create, list and remove indexes, and use cache.xml to create an index.
+
+## <a id="indexing__section_565C080FBDD0443C8504DF372E3C32C8" class="no-quick-link"></a>Creating Indexes
+
+Indexes can be created programmatically, by using the `gfsh` command line interface or by using cache.xml.
+
+To create an index, use one of the following `QueryService` methods:
+
+-   `createIndex`. Creates the default type of index, a range index. Use this type of index if you will be writing queries that will be doing any kind of comparison operation besides an equality comparison.
+-   `createKeyIndex`. Creates a key index. See [Creating Key Indexes](creating_key_indexes.html#concept_09E29507AF0D42CF81D261B030D0B7C8) for more information.
+-   `createHashIndex`. Creates a hash index. See [Creating Hash Indexes](creating_hash_indexes.html#concept_5C7614F71F394C62ACA1BDC5684A7AC4) for more information.
+-   `createDefinedIndexes`. Creates multiple indexes that were previously defined using `defineIndex`. See [Creating Multiple Indexes at Once](create_multiple_indexes.html) for more information.
+
+The following sections provide examples of index creation:
+
+**Using gfsh:**
+
+``` pre
+gfsh> create index --name=myIndex --expression=status --region=/exampleRegion
+gfsh> create index --name=myKeyIndex --type=key --expression=id --region=/exampleRegion
+gfsh> create index --name=myHashIndex --type=hash --expression=mktValue --region=/exampleRegion
+```
+
+See [Index Commands](../../tools_modules/gfsh/quick_ref_commands_by_area.html#topic_688C66526B4649AFA51C0F72F34FA45E) for more examples.
+
+**Using Java API:**
+
+``` pre
+QueryService qs = cache.getQueryService();
+ qs.createIndex("myIndex", "status", "/exampleRegion");
+ qs.createKeyIndex("myKeyIndex", "id", "/exampleRegion");
+ qs.createHashIndex("myHashIndex", "mktValue", "/exampleRegion");
+```
+
+**Using cache.xml:**
+
+``` pre
+<region name=exampleRegion>
+ <region-attributes . . . >
+ </region-attributes>
+ <index name="myIndex" from-clause="/exampleRegion" expression="status"/>
+ <index name="myKeyIndex" from-clause="/exampleRegion" expression="id" key-index="true"/>
+ <index name="myHashIndex" from-clause="/exampleRegion p" expression="p.mktValue" type="hash"/>
+ ...
+</region>
+```
+
+**Note:**
+If you do not specify the type of index in cache.xml, the type defaults to "range".
+
+## <a id="indexing__section_40089270C67A49FFA0C749E287F722F8" class="no-quick-link"></a>Listing Indexes
+
+To retrieve a list of indexes from the cache or region, use the `QueryService.getIndexes` method or the `gfsh` command line interface.
+
+**Using gfsh:**
+
+``` pre
+gfsh> list indexes
+gfsh> list indexes --with-stats
+```
+
+**Using Java API:**
+
+``` pre
+QueryService qs = cache.getQueryService();
+ qs.getIndexes(); //returns a collection of all indexes in the cache
+ qs.getIndexes(exampleRegion); //returns a collection of all indexes in exampleRegion
+ qs.getIndexes(exampleRegion, myKeyIndex); //returns the index named myKeyIndex from the exampleRegion
+```
+
+## <a id="indexing__section_ACBFB76C539A405D90B05856CB79BEFF" class="no-quick-link"></a>Removing Indexes
+
+To remove an index or all indexes from the cache or region, use the `QueryService.removeIndexes` method or the `gfsh` command line interface.
+
+**Using gfsh:**
+
+``` pre
+gfsh> destroy index
+gfsh> destroy index --name=myIndex
+gfsh> destroy index --region=/exampleRegion
+```
+
+**Using Java API:**
+
+``` pre
+QueryService qs = cache.getQueryService();
+ qs.removeIndexes(); //removes all indexes from the cache
+ qs.removeIndexes(myKeyIndex); //removes the index named myKeyIndex
+ qs.removeIndexes(exampleRegion); //removes all indexes from the exampleRegion
+```

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_index/creating_hash_indexes.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_index/creating_hash_indexes.html.md.erb b/geode-docs/developing/query_index/creating_hash_indexes.html.md.erb
new file mode 100644
index 0000000..f7fe579
--- /dev/null
+++ b/geode-docs/developing/query_index/creating_hash_indexes.html.md.erb
@@ -0,0 +1,51 @@
+---
+title:  Creating Hash Indexes
+---
+
+Geode supports the creation of hash indexes for the purposes of performing equality-based queries.
+
+## <a id="concept_5C7614F71F394C62ACA1BDC5684A7AC4__section_8A927DFB29364DA7856E7FE122FC1654" class="no-quick-link"></a>Why Create a HashIndex
+
+By creating a hash index, you can vastly improve the memory usage of your index. If you are doing equality based queries, your indexing footprint is significantly reduced. As an example, previously when you created an index that contained string fields, copies of the strings were included in the index. By using hash indexes, we ensure that indexed expressions are canonicalized and stored in the index as pointers to the objects lying in the region. In internal test cases we have seen improvements in the 30% range depending on the keys and data being used.
+
+**Note:**
+Your performance results may vary depending on the keys and data being indexed.
+
+## <a id="concept_5C7614F71F394C62ACA1BDC5684A7AC4__section_2EF23A54378E44FFBF1BEB32E41ABD61" class="no-quick-link"></a>Performance Considerations
+
+The performance of put operations when using a hash index should be comparable to other indexes or slightly slower. Queries themselves are expected to be slightly slower due to the implementation of hash index and the cost of recalculating the key on request, which is the trade-off for the space savings that using a hash index provides.
+
+## <a id="concept_5C7614F71F394C62ACA1BDC5684A7AC4__section_800401C53E5841269F389329B8A4CDF3" class="no-quick-link"></a>Limitations
+
+The following limitations must be considered when creating hash indexes:
+
+-   You can only use hash indexes with equals and not equals queries.
+-   Hash index maintenance will be slower than the other indexes due to synchronized add methods.
+-   Hash indexes cannot be maintained asynchronously. If you attempt to create a hash index on a region with asynchronous set as the maintenance mode, an exception will be thrown.
+-   You cannot use hash indexes for queries with multiple iterators or nested collections.
+
+## <a id="concept_5C7614F71F394C62ACA1BDC5684A7AC4__section_CA2476E015D14DE7B522377C931A8492" class="no-quick-link"></a>Examples of Creating a Hash Index
+
+**Using the Java API:**
+
+``` pre
+QueryService qs = cache.getQueryService();
+ qs.createHashIndex("myHashIndex", "mktValue", "/exampleRegion");
+```
+
+**Using gfsh:**
+
+``` pre
+gfsh> create index --name=myHashIndex --expression=mktValue --region=/exampleRegion
+```
+
+**Using cache.xml:**
+
+``` pre
+<region name=exampleRegion>
+ <region-attributes . . . >
+ </region-attributes>
+ <index name="myHashIndex" from-clause="/exampleRegion p" expression="p.mktValue" type="hash"/>
+ ...
+</region>
+```

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_index/creating_key_indexes.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_index/creating_key_indexes.html.md.erb b/geode-docs/developing/query_index/creating_key_indexes.html.md.erb
new file mode 100644
index 0000000..fb9de44
--- /dev/null
+++ b/geode-docs/developing/query_index/creating_key_indexes.html.md.erb
@@ -0,0 +1,49 @@
+---
+title:  Creating Key Indexes
+---
+
+Creating a key index is a good way to improve query performance when data is partitioned using a key or a field value. You can create key indexes by using the `createKeyIndex` method of the QueryService or by defining the index in `cache.xml`. Creating a key index makes the query service aware of the relationship between the values in the region and the keys in the region.
+
+The FROM clause for a primary key index must be just a region path. The indexed expression is an expression that, when applied to an entry value, produces the key. For example, if a region has Portfolios as the values and the keys are the id field of the Portfolios region, the indexed expression is id.
+
+You can then use the FunctionService (using the partitioned key as a filter passed to the function and as part of the query equality condition) to execute the query against the indexed data. See [Optimizing Queries on Data Partitioned by a Key or Field Value](../query_additional/partitioned_region_key_or_field_value.html#concept_3010014DFBC9479783B2B45982014454) for more details.
+
+There are two issues to note with key indexes:
+
+-   The key index is not sorted. Without sorting, you can only do equality tests. Other comparisons are not possible. To obtain a sorted index on your primary keys, create a functional index on the attribute used as the primary key.
+-   The query service is not automatically aware of the relationship between the region values and keys. For this, you must create the key index.
+
+**Note:**
+Using a key-index with an explicit type='range' in the cache.xml will lead to an exception. Key indexes will not be used in 'range' queries.
+
+## <a id="concept_09E29507AF0D42CF81D261B030D0B7C8__section_8F1B7893F6D44D9CB36679222927031C" class="no-quick-link"></a>Examples of Creating a Key Index
+
+**Using Java API:**
+
+``` pre
+QueryService qs = cache.getQueryService();
+ qs.createKeyIndex("myKeyIndex", "id", "/exampleRegion");
+ 
+```
+
+**Using gfsh:**
+
+``` pre
+gfsh> create index --name=myKeyIndex --expression=id --region=/exampleRegion
+```
+
+**Using cache.xml:**
+
+``` pre
+<region name=exampleRegion>
+ <region-attributes . . . >
+ </region-attributes>
+ <index name="myKeyIndex" from-clause="/exampleRegion" expression="id" key-index="true"/>
+ ...
+</region>
+```
+
+**Note:**
+If you do not specify the type of index when defining indexes using cache.xml, the type defaults to "range".
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_index/creating_map_indexes.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_index/creating_map_indexes.html.md.erb b/geode-docs/developing/query_index/creating_map_indexes.html.md.erb
new file mode 100644
index 0000000..32a5cf2
--- /dev/null
+++ b/geode-docs/developing/query_index/creating_map_indexes.html.md.erb
@@ -0,0 +1,44 @@
+---
+title:  Creating Indexes on Map Fields ("Map Indexes")
+---
+
+To assist with the quick lookup of multiple values in a Map (or HashMap) type field, you can create an index (sometimes referred to as a "map index") on specific (or all) keys in that field.
+
+For example, you could create a map index to support the following query:
+
+``` pre
+SELECT * fROM /users u WHERE u.name['first'] = 'John' OR u.name['last'] = 'Smith'
+```
+
+The map index extends regular range indexes created on single key by maintaining indexes for other specified keys, or for all keys if `*` is used. The underlying structure of the map index can be thought of as a wrapper around all these indexes.
+
+The following Java code samples provide examples of how to create a map index:
+
+``` pre
+QueryService qs = cache.getQueryService();
+
+//This will create indexes for for keys 'PVTL' and 'VMW'
+qs.createIndex("indexName", "p.positions['PVTL', 'VMW']", "/portfolio p");
+```
+
+``` pre
+QueryService qs = cache.getQueryService();
+
+//This will create indexes for all keys
+qs.createIndex("indexName", "p.positions[*]", "/portfolio p");
+```
+
+In gfsh, the equivalents are:
+
+``` pre
+gfsh>create index --name="IndexName" --expression="p.positions['PVTL', 'VMW']" --region="/portfolio p"
+
+gfsh>create index --name="IndexName" --expression="p.positions[*]" --region="/portfolio p"
+```
+
+In order to create or query a map index, you must use the bracket notation to list the map field keys you wish to index or query. For example: `[*]`, `['keyX1','keyX2’]`. Note that using `p.pos.get('keyX1')` will not create or query the map index.
+
+**Note:**
+You can still query against Map or HashMap fields without querying against a map index. For example, you can always create a regular range query on a single key in any Map or HashMap field. However, note that subsequent query lookups will be limited to a single key.
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_index/index_samples.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_index/index_samples.html.md.erb b/geode-docs/developing/query_index/index_samples.html.md.erb
new file mode 100644
index 0000000..ce2e67c
--- /dev/null
+++ b/geode-docs/developing/query_index/index_samples.html.md.erb
@@ -0,0 +1,63 @@
+---
+title:  Index Samples
+---
+
+This topic provides code samples for creating query indexes.
+
+``` pre
+ // Key index samples. The field doesn't have to be present.
+createKeyIndex("pkidIndex","p.pkid1","/root/exampleRegion p");
+ 
+createKeyIndex("Index4","ID","/portfolios");
+ 
+// Simple index
+createIndex("pkidIndex","p.pkid","/root/exampleRegion p");
+createIndex("i", "p.status", "/exampleRegion p")
+createIndex("i", "p.ID", "/exampleRegion p")
+createIndex("i", "p.position1.secId", "/exampleRegion p"
+ 
+// On Set type
+ createIndex("setIndex","s","/root/exampleRegion p, p.sp s");
+ 
+// Positions is a map
+createIndex("secIdIndex","b.secId","/portfolios pf, pf.positions.values b");
+
+//...
+createIndex("i", "pf.collectionHolderMap[(pf.Id).toString()].arr[pf.ID]", "/exampleRegion pf")
+createIndex("i", "pf.ID", "/exampleRegion pf", "pf.positions.values pos")
+createIndex("i", "pos.secId", "/exampleRegion pf", "pf.positions.values pos")
+createIndex("i", "e.value.getID()", "/exampleRegion.entrySet e")
+createIndex("i", "e.value.ID", "/exampleRegion.entrySet e")
+
+//...
+createIndex("i", "entries.value.getID", "/exampleRegion.entrySet() entries")
+createIndex("i", "ks.toString", "/exampleRegion.getKeys() ks")
+createIndex("i", "key.status", "/exampleRegion.keys key")
+createIndex("i", "secIds.length", "/exampleRegion p, p.secIds secIds")
+createIndex("i", "secId", "/portfolios.asList[1].positions.values")
+createIndex("i", "secId", "/portfolios['1'].positions.valules")
+
+//Index on Map types
+createIndex("i", "p.positions['key1']", "/exampleRegion p")
+createIndex("i", "p.positions['key1','key2',key3',key7']", "/exampleRegion p")
+createIndex("i", "p.positions[*]", "/exampleRegion p")
+```
+
+The following are some sample queries on indexes.
+
+``` pre
+SELECT * FROM (SELECT * FROM /R2 m) r2, (SELECT * FROM  /exampleRegion e WHERE e.pkid IN r2.sp) p
+
+SELECT * FROM (SELECT * FROM /R2 m WHERE m.ID IN SET (1, 5, 10)) r2, 
+     (SELECT * FROM  /exampleRegion e WHERE e.pkid IN  r2.sp) p
+
+//examples using position index in the collection
+SELECT * FROM /exampleRegion p WHERE p.names[0] = 'aaa'
+
+SELECT * FROM /exampleRegion p WHERE p.position3[1].portfolioId = 2
+
+SELECT DISTINCT positions.values.toArray[0], positions.values.toArray[0], status 
+FROM /exampleRegion
+```
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_index/indexes_on_single_region_queries.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_index/indexes_on_single_region_queries.html.md.erb b/geode-docs/developing/query_index/indexes_on_single_region_queries.html.md.erb
new file mode 100644
index 0000000..35662f7
--- /dev/null
+++ b/geode-docs/developing/query_index/indexes_on_single_region_queries.html.md.erb
@@ -0,0 +1,33 @@
+---
+title:  Using Indexes on Single Region Queries
+---
+
+Queries with one comparison operation may be improved with either a key or range index, depending on whether the attribute being compared is also the primary key.
+
+<a id="concept_0210701C193A470E8C572111F6CEC3FC__section_751427643EC3480BABCE9CA44E831E27"></a>
+If pkid is the key in the /exampleRegion region, creating a key index on pkid is the best choice as a key index does not have maintenance overhead. If pkid is not the key, a range index on pkid should improve performance.
+
+``` pre
+SELECT DISTINCT * FROM /exampleRegion portfolio WHERE portfolio.pkid = '123'
+```
+
+With multiple comparison operations, you can create a range index on one or more of the attributes. Try the following:
+
+1.  Create a single index on the condition you expect to have the smallest result set size. Check performance with this index.
+2.  Keeping the first index, add an index on a second condition. Adding the second index may degrade performance. If it does, remove it and keep only the first index. The order of the two comparisons in the query can also impact performance. Generally speaking, in OQL queries, as in SQL queries, you should order your comparisons so the earlier ones give you the fewest results on which to run subsequent comparisons.
+
+For this query, you would try a range index on name, age, or on both:
+
+``` pre
+SELECT DISTINCT * FROM /exampleRegion portfolio WHERE portfolio.status = 'active' and portfolio.ID > 45
+```
+
+For queries with nested levels, you may get better performance by drilling into the lower levels in the index as well as in the query.
+
+This query drills down one level:
+
+``` pre
+SELECT DISTINCT * FROM /exampleRegion portfolio, portfolio.positions.values positions where positions.secId = 'AOL' and positions.MktValue > 1
+```
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_index/indexes_with_overflow_regions.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_index/indexes_with_overflow_regions.html.md.erb b/geode-docs/developing/query_index/indexes_with_overflow_regions.html.md.erb
new file mode 100644
index 0000000..126b2e6
--- /dev/null
+++ b/geode-docs/developing/query_index/indexes_with_overflow_regions.html.md.erb
@@ -0,0 +1,41 @@
+---
+title:  Using Indexes with Overflow Regions
+---
+
+You can use indexes when querying on overflow regions; however, there are caveats.
+
+The following are caveats for querying overflow regions:
+
+-   You must use synchronous index maintenance for the region. This is the default maintenance setting.
+-   The index FROM clause must specify only one iterator, and it must refer to the keys or entry values. The index cannot refer to the region’s entrySet.
+-   The index data itself is not stored on (overflowed to) disk .
+
+**Examples:**
+
+The following example index creation calls DO NOT work for overflow regions.
+
+``` pre
+// This index will not work on an overflow region because there are two iterators in the FROM clause.
+createIndex("secIdIndex", "b.secId","/portfolios pf, pf.positions.values b");
+
+// This index will not work on an overflow region because the FROM clause specifies the entrySet
+createIndex("indx1", "entries.value.getID", "/exampleRegion.entrySet() entries");
+```
+
+The following example indexes will work for overflow regions.
+
+``` pre
+createIndex("pkidIndex", "p.pkid", "/Portfolios p");
+
+createIndex("indx1", "ks.toString", "/portfolio.keySet() ks");
+```
+
+The same working examples in gfsh:
+
+``` pre
+gfsh> create index -name="pkidIndex" --expression="p.pkid" --region="/Portfolios p"
+
+gfsh> create index -name="indx1" --expression="ks.toString" --region="/portfolio.keySet() ks"
+```
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_index/indexing_guidelines.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_index/indexing_guidelines.html.md.erb b/geode-docs/developing/query_index/indexing_guidelines.html.md.erb
new file mode 100644
index 0000000..8cf229f
--- /dev/null
+++ b/geode-docs/developing/query_index/indexing_guidelines.html.md.erb
@@ -0,0 +1,24 @@
+---
+title:  Tips and Guidelines on Using Indexes
+---
+
+Optimizing your queries with indexes requires a cycle of careful planning, testing, and tuning. Poorly-defined indexes can degrade the performance of your queries instead of improving it. This section gives guidelines for index usage in the query service.
+
+<a id="indexing_guidelines__section_A8885DFC334243508C4563C9692E0801"></a>
+When creating indexes, keep in mind the following:
+
+-   Indexes incur maintenance costs as they must be updated when the indexed data changes. An index that requires many updates and is not used very often may require more system resources than using no index at all.
+-   Indexes consume memory.
+-   Indexes have limited support on overflow regions. See [Using Indexes with Overflow Regions](indexes_with_overflow_regions.html#concept_87BE7DB32C714EB0BF7532AF93569328) for details.
+-   If you are creating multiple indexes on the same region, first define your indexes and then create the indexes all at once to avoid iterating over the region multiple times. See [Creating Multiple Indexes at Once](create_multiple_indexes.html) for details.
+
+## <a id="indexing_guidelines__section_A8AFAA243B5C43DD9BB9F9235A48AF53" class="no-quick-link"></a>Tips for Writing Queries that Use Indexes
+
+As with query processors that run against relational databases, the way a query is written can greatly affect execution performance. Among other things, whether indexes are used depends on how each query is stated. These are some of the things to consider when optimizing your Geode queries for performance:
+
+-   In general an index will improve query performance if the FROM clauses of the query and index match exactly.
+-   The query evaluation engine does not have a sophisticated cost-based optimizer. It has a simple optimizer which selects best index (one) or multiple indexes based on the index size and the operator that is being evaluated.
+-   For AND operators, you may get better results if the conditions that use indexes and conditions that are more selective come before other conditions in the query.
+-   Indexes are not used in expressions that contain NOT, so in a WHERE clause of a query, `qty >= 10` could have an index on `qty` applied for efficiency. However, `NOT(qty < 10)` could not have the same index applied.
+-   Whenever possible, provide a hint to allow the query engine to prefer a specific index. See [Using Query Index Hints](query_index_hints.html)
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_index/maintaining_indexes.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_index/maintaining_indexes.html.md.erb b/geode-docs/developing/query_index/maintaining_indexes.html.md.erb
new file mode 100644
index 0000000..ae8c29b
--- /dev/null
+++ b/geode-docs/developing/query_index/maintaining_indexes.html.md.erb
@@ -0,0 +1,52 @@
+---
+title:  Maintaining Indexes (Synchronously or Asynchronously) and Index Storage
+---
+
+Indexes are automatically kept current with the region data they reference. The region attribute `IndexMaintenanceSynchronous` specifies whether the region indexes are updated synchronously when a region is modified or asynchronously in a background thread.
+
+## <a id="concept_98ED3F38919A490B9AE2553568455C35__section_FF1945F2AAFA4B158067CEE967410616" class="no-quick-link"></a>Index Maintenance Behavior
+
+Asynchronous index maintenance batches up multiple updates to the same region key. The default mode is synchronous, since this provides the greatest consistency with region data.
+
+See [RegionFactory.setIndexMaintenanceSynchronous](/releases/latest/javadoc/org/apache/geode/cache/RegionFactory.html).
+
+This declarative index creation sets the maintenance mode to asynchronous:
+
+``` pre
+<region-attributes index-update-type="asynchronous"> 
+</region-attributes>
+```
+
+## <a id="concept_98ED3F38919A490B9AE2553568455C35__section_68308B5597CF4A9EAA8EC0BD83A233E6" class="no-quick-link"></a>Internal Index Structure and Storage
+
+Indexes are stored either as compact or non-compact data structures based on the indexed expression (even if the index key type is the same.) For example, consider the following Passenger object:
+
+``` pre
+Passenger {
+   String name,
+   Date travelDate,
+   int age,
+   Flight flt,
+}
+Flight {
+   int flightId,
+   String origin,
+   String dest,
+}
+```
+
+An index on the Passenger name field will have different memory space requirements in the cache than the Flight origin field even though they are both String field types. The internal data structure selected by Geode for index storage will depend on the field's level in the object. In this example, name is a top-level field and an index on name can be stored as a compact index. Since origin is a second-level field, any index that uses origin as the indexed expression will be stored as a non-compact index.
+
+**Compact Index**
+
+A compact index has simple data structures to minimize its footprint, at the expense of doing extra work at index maintenance. This index does not support the storage of projection attributes.
+
+Currently compact indexes are only selected only supports the creation of an index on a region path. In addition, the following conditions must be met:
+
+-   Index maintenance is synchronous.
+-   The indexed expression is a path expression.
+-   The FROM clause has only one iterator. This implies that there is only one value in the index for each region entry and it is directly on the region values (not supported with keys, entries).
+
+**Non-Compact Index**
+
+Used whenever a compact index cannot be used.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_index/query_index.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_index/query_index.html.md.erb b/geode-docs/developing/query_index/query_index.html.md.erb
new file mode 100644
index 0000000..accbf00
--- /dev/null
+++ b/geode-docs/developing/query_index/query_index.html.md.erb
@@ -0,0 +1,62 @@
+---
+title:  Working with Indexes
+---
+
+The Geode query engine supports indexing. An index can provide significant performance gains for query execution.
+
+<a id="indexing__section_565C080FBDD0443C8504DF372E3C32C8"></a>
+A query run without the aid of an index iterates through every object in the collection. If an index is available that matches part or all of the query specification, the query iterates only over the indexed set, and query processing time can be reduced.
+
+-   **[Tips and Guidelines on Using Indexes](../../developing/query_index/indexing_guidelines.html)**
+
+    Optimizing your queries with indexes requires a cycle of careful planning, testing, and tuning. Poorly-defined indexes can degrade the performance of your queries instead of improving it. This section gives guidelines for index usage in the query service.
+
+-   **[Creating, Listing and Removing Indexes](../../developing/query_index/creating_an_index.html)**
+
+    The Geode `QueryService` API provides methods to create, list and remove the index. You can also use `gfsh` command-line interface to create, list and remove indexes, and use cache.xml to create an index.
+
+-   **[Creating Key Indexes](../../developing/query_index/creating_key_indexes.html)**
+
+    Creating a key index is a good way to improve query performance when data is partitioned using a key or a field value. You can create key indexes by using the `createKeyIndex` method of the QueryService or by defining the index in `cache.xml`. Creating a key index makes the query service aware of the relationship between the values in the region and the keys in the region.
+
+-   **[Creating Hash Indexes](../../developing/query_index/creating_hash_indexes.html)**
+
+    Geode supports the creation of hash indexes for the purposes of performing equality-based queries.
+
+-   **[Creating Indexes on Map Fields ("Map Indexes")](../../developing/query_index/creating_map_indexes.html)**
+
+    To assist with the quick lookup of multiple values in a Map (or HashMap) type field, you can create an index (sometimes referred to as a "map index") on specific (or all) keys in that field.
+
+-   **[Creating Multiple Indexes at Once](../../developing/query_index/create_multiple_indexes.html)**
+
+    In order to speed and promote efficiency when creating indexes, you can define multiple indexes and then create them all at once.
+
+-   **[Maintaining Indexes (Synchronously or Asynchronously) and Index Storage](../../developing/query_index/maintaining_indexes.html)**
+
+    Indexes are automatically kept current with the region data they reference. The region attribute `IndexMaintenanceSynchronous` specifies whether the region indexes are updated synchronously when a region is modified or asynchronously in a background thread.
+
+-   **[Using Query Index Hints](../../developing/query_index/query_index_hints.html)**
+
+    You can use the hint keyword to allow Geode's query engine to prefer certain indexes.
+
+-   **[Using Indexes on Single Region Queries](../../developing/query_index/indexes_on_single_region_queries.html)**
+
+    Queries with one comparison operation may be improved with either a key or range index, depending on whether the attribute being compared is also the primary key.
+
+-   **[Using Indexes with Equi-Join Queries](../../developing/query_index/using_indexes_with_equijoin_queries.html)**
+
+    Equi-join queries are queries in which two regions are joined through an equality condition in the WHERE clause.
+
+-   **[Using Indexes with Overflow Regions](../../developing/query_index/indexes_with_overflow_regions.html)**
+
+    You can use indexes when querying on overflow regions; however, there are caveats.
+
+-   **[Using Indexes on Equi-Join Queries using Multiple Regions](../../developing/query_index/using_indexes_with_equijoin_queries_multiple_regions.html)**
+
+    To query across multiple regions, identify all equi-join conditions. Then, create as few indexes for the equi-join conditions as you can while still joining all regions.
+
+-   **[Index Samples](../../developing/query_index/index_samples.html)**
+
+    This topic provides code samples for creating query indexes.
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_index/query_index_hints.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_index/query_index_hints.html.md.erb b/geode-docs/developing/query_index/query_index_hints.html.md.erb
new file mode 100644
index 0000000..37b1005
--- /dev/null
+++ b/geode-docs/developing/query_index/query_index_hints.html.md.erb
@@ -0,0 +1,23 @@
+---
+title:  Using Query Index Hints
+---
+
+You can use the hint keyword to allow Geode's query engine to prefer certain indexes.
+
+In cases where one index is hinted in a query, the query engine filters off the hinted index (if possible) and then iterates and filters from the resulting values.
+
+**Example:**
+
+``` pre
+<HINT 'IDIndex'> SELECT * FROM /Portfolios p WHERE p.ID > 10 AND p.owner = 'XYZ'
+```
+
+If multiple indexes are added as hints, then the query engine will try to use as many indexes as possible while giving a preference for the hinted indexes.
+
+**Example:**
+
+``` pre
+<HINT 'IDIndex', 'OwnerIndex'> SELECT * FROM /Portfolios p WHERE p.ID > 10 AND p.owner = 'XYZ' AND p.value < 100
+```
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ccc2fbda/geode-docs/developing/query_index/using_indexes_with_equijoin_queries.html.md.erb
----------------------------------------------------------------------
diff --git a/geode-docs/developing/query_index/using_indexes_with_equijoin_queries.html.md.erb b/geode-docs/developing/query_index/using_indexes_with_equijoin_queries.html.md.erb
new file mode 100644
index 0000000..2d7accc
--- /dev/null
+++ b/geode-docs/developing/query_index/using_indexes_with_equijoin_queries.html.md.erb
@@ -0,0 +1,52 @@
+---
+title:  Using Indexes with Equi-Join Queries
+---
+
+Equi-join queries are queries in which two regions are joined through an equality condition in the WHERE clause.
+
+<a id="concept_A90C5FD84FCB45B2B28D6CE78DE1D117__section_47CFF4EF4D964FCFBB772B0347C02214"></a>
+To use an index with an equi-join query:
+
+1.  Create an index for each side of the equi-join condition. The query engine can quickly evaluate the query's equi-join condition by iterating over the keys of the left-side and right-side indexes for an equality match.
+
+    **Note:**
+    Equi-join queries require regular indexes. Key indexes are not applied to equi-join queries.
+
+    For this query:
+
+    ``` pre
+    SELECT DISTINCT inv.name, ord.orderID, ord.status 
+    FROM /investors inv, /orders ord 
+    WHERE inv.investorID = ord.investorID 
+    ```
+
+    Create two indexes:
+
+    | FROM clause    | Indexed expression |
+    |----------------|--------------------|
+    | /investors inv | inv.investorID     |
+    | /orders ord    | ord.investorID     |
+
+2.  If there are additional, single-region queries in a query with an equi-join condition, create additional indexes for the single-region conditions only if you are able to create at least one such index for each region in the query. Any indexing on a subset of the regions in the query will degrade performance.
+
+    For this example query:
+
+    ``` pre
+    SELECT DISTINCT *
+    FROM /investors inv, /securities sc, inv.heldSecurities inv_hs
+        WHERE sc.status = "active"
+        AND inv.name = "xyz"
+        AND inv.age > 75
+        AND inv_hs.secName = sc.secName
+    ```
+
+    Create the indexes for the equi-join condition:
+
+    | FROM clause                                | Indexed expression |
+    |--------------------------------------------|--------------------|
+    | /investors inv, inv.heldSecurities inv\_hs | inv\_hs.secName    |
+    | /securities sc                             | sc.secName         |
+
+    Then, if you create any more indexes, create one on `sc.status` and one on `inv.age` or `inv.name` or both.
+
+


Mime
View raw message