usergrid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From toddn...@apache.org
Subject [13/33] incubator-usergrid git commit: Type coercion from int->long and float->double implemented.
Date Mon, 13 Apr 2015 19:18:20 GMT
Type coercion from int->long and float->double implemented.

Implemented query/filter IR tree collapsing to avoid invalid requests

Moved all queries to filters for performance except wildcard and contains operation


Project: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/commit/96555347
Tree: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/tree/96555347
Diff: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/diff/96555347

Branch: refs/heads/two-dot-o-dev
Commit: 965553478d70369112edb88b63843dc9a52ade9e
Parents: 8f70c7c
Author: Todd Nine <tnine@apigee.com>
Authored: Tue Apr 7 17:02:43 2015 -0600
Committer: Todd Nine <tnine@apigee.com>
Committed: Tue Apr 7 17:06:36 2015 -0600

----------------------------------------------------------------------
 .../persistence/index/impl/EntityField.java     |   4 +-
 .../index/impl/EntityMappingParser.java         |   2 +-
 .../index/impl/EsEntityIndexBatchImpl.java      |  54 +-
 .../index/impl/EsIndexBufferConsumerImpl.java   |   1 +
 .../persistence/index/impl/EsQueryVistor.java   | 496 ++++++++++++-------
 .../persistence/index/impl/IndexEdgeImpl.java   |  37 +-
 .../persistence/index/impl/IndexingUtils.java   |  27 +-
 .../index/impl/NoOpFilterBuilder.java           |  45 ++
 .../index/impl/NoOpQueryBuilder.java            |  45 ++
 .../persistence/index/impl/SearchEdgeImpl.java  |  46 +-
 .../impl/SearchRequestBuilderStrategy.java      |  52 +-
 .../index/query/ParsedQueryBuilder.java         |   2 +-
 .../index/query/tree/QueryVisitor.java          |  16 +-
 .../persistence/index/usergrid-mappings.json    |   8 -
 .../index/impl/EntityToMapConverterTest.java    |  16 +-
 .../src/test/resources/log4j.properties         |   5 +
 .../queryindex/src/test/resources/test.json     | 133 +++++
 17 files changed, 727 insertions(+), 262 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityField.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityField.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityField.java
index 0585d6a..7e7c610 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityField.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityField.java
@@ -76,7 +76,7 @@ public class EntityField extends HashMap<String, Object> {
     public static EntityField create( final String fieldName, final int value ) {
         EntityField field = new EntityField();
         field.put( IndexingUtils.FIELD_NAME, fieldName );
-        field.put( IndexingUtils.FIELD_INT, value );
+        field.put( IndexingUtils.FIELD_LONG, value );
 
         return field;
     }
@@ -100,7 +100,7 @@ public class EntityField extends HashMap<String, Object> {
     public static EntityField create( final String fieldName, final float value ) {
         EntityField field = new EntityField();
         field.put( IndexingUtils.FIELD_NAME, fieldName );
-        field.put( IndexingUtils.FIELD_FLOAT, value );
+        field.put( IndexingUtils.FIELD_DOUBLE, value );
 
         return field;
     }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityMappingParser.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityMappingParser.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityMappingParser.java
index eac4376..0369ff0 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityMappingParser.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityMappingParser.java
@@ -67,7 +67,7 @@ public class EntityMappingParser implements FieldParser {
      * Visit al the primitive values
      */
     private void visit( final String value ) {
-        fields.add( EntityField.create( fieldStack.peek(), value ) );
+        fields.add( EntityField.create( fieldStack.peek(), value.toLowerCase() ) );
     }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexBatchImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexBatchImpl.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexBatchImpl.java
index 852dee2..d22f000 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexBatchImpl.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexBatchImpl.java
@@ -18,21 +18,25 @@
  */
 package org.apache.usergrid.persistence.index.impl;
 
-import java.util.*;
 
-import org.apache.usergrid.persistence.core.future.BetterFuture;
-import org.apache.usergrid.persistence.index.*;
+import java.util.UUID;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.usergrid.persistence.core.future.BetterFuture;
 import org.apache.usergrid.persistence.core.scope.ApplicationScope;
 import org.apache.usergrid.persistence.core.util.ValidationUtils;
+import org.apache.usergrid.persistence.index.AliasedEntityIndex;
+import org.apache.usergrid.persistence.index.CandidateResult;
+import org.apache.usergrid.persistence.index.EntityIndexBatch;
+import org.apache.usergrid.persistence.index.IndexEdge;
+import org.apache.usergrid.persistence.index.SearchEdge;
 import org.apache.usergrid.persistence.index.utils.IndexValidationUtils;
 import org.apache.usergrid.persistence.model.entity.Entity;
 import org.apache.usergrid.persistence.model.entity.Id;
 
 
-
 public class EsEntityIndexBatchImpl implements EntityIndexBatch {
 
     private static final Logger log = LoggerFactory.getLogger( EsEntityIndexBatchImpl.class );
@@ -48,10 +52,10 @@ public class EsEntityIndexBatchImpl implements EntityIndexBatch {
     private IndexIdentifierImpl.IndexOperationMessage container;
 
 
-
-    public EsEntityIndexBatchImpl(final ApplicationScope applicationScope,
-                                  final IndexBufferProducer indexBatchBufferProducer,
-                                  final AliasedEntityIndex entityIndex, FailureMonitorImpl.IndexIdentifier indexIdentifier ) {
+    public EsEntityIndexBatchImpl( final ApplicationScope applicationScope,
+                                   final IndexBufferProducer indexBatchBufferProducer,
+                                   final AliasedEntityIndex entityIndex,
+                                   FailureMonitorImpl.IndexIdentifier indexIdentifier ) {
 
         this.applicationScope = applicationScope;
         this.indexBatchBufferProducer = indexBatchBufferProducer;
@@ -69,26 +73,39 @@ public class EsEntityIndexBatchImpl implements EntityIndexBatch {
         ValidationUtils.verifyEntityWrite( entity );
         ValidationUtils.verifyVersion( entity.getVersion() );
 
+        final String writeAlias = alias.getWriteAlias();
+
+        if ( log.isDebugEnabled() ) {
+            log.debug( "Indexing to alias {} with scope {} on edge {} with entity data {}",
+                    new Object[] { writeAlias, applicationScope, indexEdge, entity } );
+        }
+
         //add app id for indexing
-        container.addIndexRequest(new IndexRequest(alias.getWriteAlias(), applicationScope, indexEdge, entity));
+        container.addIndexRequest( new IndexRequest( writeAlias, applicationScope, indexEdge, entity ) );
         return this;
     }
 
 
     @Override
-    public EntityIndexBatch deindex( final SearchEdge searchEdge, final Id id, final UUID version) {
+    public EntityIndexBatch deindex( final SearchEdge searchEdge, final Id id, final UUID version ) {
 
         IndexValidationUtils.validateSearchEdge( searchEdge );
-        ValidationUtils.verifyIdentity(id);
+        ValidationUtils.verifyIdentity( id );
         ValidationUtils.verifyVersion( version );
 
         String[] indexes = entityIndex.getUniqueIndexes();
         //get the default index if no alias exists yet
-        if(indexes == null ||indexes.length == 0){
-            indexes = new String[]{indexIdentifier.getIndex(null)};
+        if ( indexes == null || indexes.length == 0 ) {
+            indexes = new String[] { indexIdentifier.getIndex( null ) };
+        }
+
+        if ( log.isDebugEnabled() ) {
+            log.debug( "Deindexing to indexes {} with scope {} on edge {} with id {} and version {} ",
+                    new Object[] { indexes, applicationScope, searchEdge, id, version } );
         }
 
-        container.addDeIndexRequest(new DeIndexRequest(indexes, applicationScope, searchEdge,id,version));
+
+        container.addDeIndexRequest( new DeIndexRequest( indexes, applicationScope, searchEdge, id, version ) );
 
         return this;
     }
@@ -106,6 +123,7 @@ public class EsEntityIndexBatchImpl implements EntityIndexBatch {
         return deindex( searchEdge, entity.getId(), entity.getVersion() );
     }
 
+
     @Override
     public BetterFuture execute() {
         IndexIdentifierImpl.IndexOperationMessage tempContainer = container;
@@ -114,12 +132,12 @@ public class EsEntityIndexBatchImpl implements EntityIndexBatch {
         /**
          * No-op, just disregard it
          */
-        if(tempContainer.isEmpty()){
+        if ( tempContainer.isEmpty() ) {
             tempContainer.done();
             return tempContainer.getFuture();
         }
 
-        return indexBatchBufferProducer.put(tempContainer);
+        return indexBatchBufferProducer.put( tempContainer );
     }
 
 
@@ -127,8 +145,4 @@ public class EsEntityIndexBatchImpl implements EntityIndexBatch {
     public int size() {
         return container.getDeIndexRequests().size() + container.getIndexRequests().size();
     }
-
-
-
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsIndexBufferConsumerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsIndexBufferConsumerImpl.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsIndexBufferConsumerImpl.java
index 0648e9b..e55fcc2 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsIndexBufferConsumerImpl.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsIndexBufferConsumerImpl.java
@@ -277,6 +277,7 @@ public class EsIndexBufferConsumerImpl implements IndexBufferConsumer {
 
         final BulkResponse responses;
 
+
         try {
             responses = bulkRequest.execute().actionGet();
         } catch (Throwable t) {

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsQueryVistor.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsQueryVistor.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsQueryVistor.java
index 2e2509a..9f0e68f 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsQueryVistor.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsQueryVistor.java
@@ -19,21 +19,23 @@
 package org.apache.usergrid.persistence.index.impl;
 
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.Stack;
-import java.util.UUID;
-
-import javax.swing.text.html.Option;
 
 import org.elasticsearch.common.unit.DistanceUnit;
+import org.elasticsearch.index.query.BoolFilterBuilder;
 import org.elasticsearch.index.query.BoolQueryBuilder;
 import org.elasticsearch.index.query.FilterBuilder;
 import org.elasticsearch.index.query.FilterBuilders;
+import org.elasticsearch.index.query.MatchQueryBuilder;
+import org.elasticsearch.index.query.NestedFilterBuilder;
+import org.elasticsearch.index.query.NestedQueryBuilder;
 import org.elasticsearch.index.query.QueryBuilder;
 import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.index.query.RangeFilterBuilder;
+import org.elasticsearch.index.query.TermFilterBuilder;
+import org.elasticsearch.index.query.WildcardQueryBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -52,19 +54,26 @@ import org.apache.usergrid.persistence.index.query.tree.OrOperand;
 import org.apache.usergrid.persistence.index.query.tree.QueryVisitor;
 import org.apache.usergrid.persistence.index.query.tree.WithinOperand;
 
-import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
 
 
 /**
- * Visits tree of  parsed Query operands and populates
- * ElasticSearch QueryBuilder that represents the query.
+ * Visits tree of  parsed Query operands and populates ElasticSearch QueryBuilder that represents the query.
  */
 public class EsQueryVistor implements QueryVisitor {
     private static final Logger logger = LoggerFactory.getLogger( EsQueryVistor.class );
 
-    Stack<QueryBuilder> stack = new Stack<QueryBuilder>();
-    List<FilterBuilder> filterBuilders = new ArrayList<FilterBuilder>();
+    /**
+     * Our queryBuilders for query operations
+     */
+    private final Stack<QueryBuilder> queryBuilders = new Stack<>();
+
+    /**
+     * Our queryBuilders for filter operations
+     */
+    private final Stack<FilterBuilder> filterBuilders = new Stack<>();
+
+    private final Set<String> geoFields = new HashSet<String>();
 
 
     @Override
@@ -72,43 +81,68 @@ public class EsQueryVistor implements QueryVisitor {
 
 
         op.getLeft().visit( this );
-        QueryBuilder left = null;
+        op.getRight().visit( this );
 
-        // special handling for WithinOperand because ElasticSearch wants us to use
-        // a filter and not have WithinOperand as part of the actual query itself
-        if ( !(op.getLeft() instanceof WithinOperand) ) {
-            left = stack.peek();
-        }
+        //get all the right
+        final QueryBuilder rightQuery = queryBuilders.pop();
+        final FilterBuilder rightFilter = filterBuilders.pop();
 
-        op.getRight().visit( this );
-        QueryBuilder right = null;
 
-        // special handling for WithinOperand on the right too
-        if ( !(op.getRight()instanceof WithinOperand) ) {
-            right = stack.peek();
-        }
+        //get all the left
+        final QueryBuilder leftQuery = queryBuilders.pop();
+        final FilterBuilder leftFilter = filterBuilders.pop();
 
-        if ( left == right ) {
-            return;
-        }
 
-        if ( !(op.getLeft() instanceof WithinOperand) ) {
-            left = stack.pop();
+        //push our boolean filters
+
+
+        final boolean useLeftQuery = use( leftQuery );
+        final boolean useRightQuery = use( rightQuery );
+
+        /**
+         * We use a left and a right, add our boolean query
+         */
+        if ( useLeftQuery && useRightQuery ) {
+            final BoolQueryBuilder qb = QueryBuilders.boolQuery().must( leftQuery ).must( rightQuery );
+            queryBuilders.push( qb );
+        }
+        //only use the left
+        else if ( useLeftQuery ) {
+            queryBuilders.push( leftQuery );
+        }
+        //only use the right
+        else if ( useRightQuery ) {
+            queryBuilders.push( rightQuery );
+        }
+        //put in an empty in case we're not the root.  I.E X and Y and Z
+        else{
+            queryBuilders.push( NoOpQueryBuilder.INSTANCE );
         }
 
-        if ( !(op.getRight()instanceof WithinOperand) ) {
-            right = stack.pop();
+        //possibly use neither if the is a no-op
+
+
+        final boolean useLeftFilter = use( leftFilter );
+        final boolean useRightFilter = use( rightFilter );
+
+        //use left and right
+        if ( useLeftFilter && useRightFilter ) {
+            final BoolFilterBuilder fb = FilterBuilders.boolFilter().must( leftFilter ).must( rightFilter );
+            filterBuilders.push( fb );
         }
 
-        BoolQueryBuilder qb = QueryBuilders.boolQuery();
-        if ( left != null ) {
-            qb = qb.must( left );
+        //only use left
+        else if ( useLeftFilter ) {
+            filterBuilders.push( leftFilter );
         }
-        if ( right != null ) {
-            qb = qb.must( right );
+        //only use right
+        else if ( useRightFilter ) {
+            filterBuilders.push( rightFilter );
+        }
+        //push in a no-op in case we're not the root   I.E X and Y and Z
+        else{
+            filterBuilders.push( NoOpFilterBuilder.INSTANCE );
         }
-
-        stack.push( qb );
     }
 
 
@@ -118,24 +152,58 @@ public class EsQueryVistor implements QueryVisitor {
         op.getLeft().visit( this );
         op.getRight().visit( this );
 
-        QueryBuilder left = null;
-        if ( !(op.getLeft()instanceof WithinOperand) ) {
-            left = stack.pop();
+        final QueryBuilder rightQuery = queryBuilders.pop();
+        final FilterBuilder rightFilter = filterBuilders.pop();
+
+
+        //get all the left
+        final QueryBuilder leftQuery = queryBuilders.pop();
+        final FilterBuilder leftFilter = filterBuilders.pop();
+
+
+        final boolean useLeftQuery = use( leftQuery );
+        final boolean useRightQuery = use( rightQuery );
+
+        //push our boolean filters
+        if ( useLeftQuery && useRightQuery ) {
+            final BoolQueryBuilder qb = QueryBuilders.boolQuery().should( leftQuery ).should( rightQuery );
+            queryBuilders.push( qb );
+        }
+        else if ( useLeftQuery ) {
+            queryBuilders.push( leftQuery );
         }
-        QueryBuilder right = null;
-        if ( !(op.getRight()instanceof WithinOperand) ) {
-            right = stack.pop();
+        else if ( useRightQuery ) {
+            queryBuilders.push( rightQuery );
         }
 
-        BoolQueryBuilder qb = QueryBuilders.boolQuery();
-        if ( left != null ) {
-            qb = qb.should( left );
+         //put in an empty in case we're not the root.  I.E X or Y or Z
+        else{
+            queryBuilders.push( NoOpQueryBuilder.INSTANCE );
         }
-        if ( right != null ) {
-            qb = qb.should( right );
+
+
+        final boolean useLeftFilter = use( leftFilter );
+        final boolean useRightFilter = use( rightFilter );
+
+        //use left and right
+        if ( useLeftFilter && useRightFilter ) {
+            final BoolFilterBuilder fb = FilterBuilders.boolFilter().should( leftFilter ).should( rightFilter );
+            filterBuilders.push( fb );
+        }
+
+        //only use left
+        else if ( useLeftFilter ) {
+            filterBuilders.push( leftFilter );
+        }
+        //only use right
+        else if ( useRightFilter ) {
+            filterBuilders.push( rightFilter );
+        }
+         //put in an empty in case we're not the root.  I.E X or Y or Z
+        else{
+            queryBuilders.push( NoOpQueryBuilder.INSTANCE );
         }
 
-        stack.push( qb );
     }
 
 
@@ -143,232 +211,306 @@ public class EsQueryVistor implements QueryVisitor {
     public void visit( NotOperand op ) throws IndexException {
         op.getOperation().visit( this );
 
-        if ( !(op.getOperation() instanceof WithinOperand) ) {
-            stack.push( QueryBuilders.boolQuery().mustNot( stack.pop() ));
+        //push our not operation into our query
+
+        final QueryBuilder notQueryBuilder = queryBuilders.pop();
+
+        if ( use( notQueryBuilder ) ) {
+            queryBuilders.push( QueryBuilders.boolQuery().mustNot( notQueryBuilder ) );
+        }
+        else{
+            queryBuilders.push( NoOpQueryBuilder.INSTANCE );
+        }
+
+        final FilterBuilder notFilterBuilder = filterBuilders.pop();
+
+        //push the filter in
+        if ( use( notFilterBuilder ) ) {
+            filterBuilders.push( FilterBuilders.boolFilter().mustNot( notFilterBuilder ) );
+        }
+        else{
+            filterBuilders.push( NoOpFilterBuilder.INSTANCE );
         }
     }
 
 
     @Override
     public void visit( ContainsOperand op ) throws NoFullTextIndexException {
-        String name = op.getProperty().getValue();
-        name = name.toLowerCase();
-        Object value = op.getLiteral().getValue();
+        final String name = op.getProperty().getValue().toLowerCase();
+        final String value = op.getLiteral().getValue().toString().toLowerCase();
+
+
+        // or field is just a string that does need a prefix
+        if ( value.indexOf( "*" ) != -1 ) {
+            final WildcardQueryBuilder wildcardQuery =
+                    QueryBuilders.wildcardQuery( IndexingUtils.FIELD_STRING_NESTED, value );
+            queryBuilders.push( fieldNameTerm( name, wildcardQuery ) );
+        }
+        else {
+            final MatchQueryBuilder termQuery = QueryBuilders.matchQuery( IndexingUtils.FIELD_STRING_NESTED, value );
 
-        BoolQueryBuilder qb = QueryBuilders.boolQuery(); // let's do a boolean OR
-        qb.minimumNumberShouldMatch(1);
+            queryBuilders.push( fieldNameTerm( name, termQuery ) );
+        }
 
-        // field is an entity/array that needs no name prefix
-        qb = qb.should( QueryBuilders.matchQuery( name, value ) );
 
-        // OR field is a string and needs the prefix on the name
-        qb = qb.should( QueryBuilders.matchQuery( addPrefix( value.toString(), name, true), value));
+        //no op for filters, push an empty operation
 
-        stack.push( qb );
+        //TODO, validate this works
+        filterBuilders.push( NoOpFilterBuilder.INSTANCE );
     }
 
 
     @Override
     public void visit( WithinOperand op ) {
 
-        String name = op.getProperty().getValue();
-        name = name.toLowerCase();
+        final String name = op.getProperty().getValue().toLowerCase();
+
+        geoFields.add( name );
 
         float lat = op.getLatitude().getFloatValue();
         float lon = op.getLongitude().getFloatValue();
         float distance = op.getDistance().getFloatValue();
 
 
+        final FilterBuilder fb = FilterBuilders.geoDistanceFilter( name ).lat( lat ).lon( lon )
+                                               .distance( distance, DistanceUnit.METERS );
+        filterBuilders.push( fb );
+
+        //no op for query, push
 
-        FilterBuilder fb = FilterBuilders.geoDistanceFilter( name )
-           .lat( lat ).lon( lon ).distance( distance, DistanceUnit.METERS );
-        filterBuilders.add( fb );
+        queryBuilders.push( NoOpQueryBuilder.INSTANCE );
     }
 
 
     @Override
     public void visit( LessThan op ) throws NoIndexException {
-        String name = op.getProperty().getValue();
-        name = name.toLowerCase();
-        Object value = op.getLiteral().getValue();
-        name = addPrefix( value, name );
-        stack.push( QueryBuilders.rangeQuery( name ).lt( value ));
+        final String name = op.getProperty().getValue().toLowerCase();
+        final Object value = op.getLiteral().getValue();
+
+
+        final RangeFilterBuilder termQuery =
+                FilterBuilders.rangeFilter( getFieldNameForType( value ) ).lt( sanitize( value ) );
+
+
+        queryBuilders.push( NoOpQueryBuilder.INSTANCE );
+
+        //we do this by query, push empty
+
+        filterBuilders.push( fieldNameTerm( name, termQuery ) );
     }
 
 
     @Override
     public void visit( LessThanEqual op ) throws NoIndexException {
-        String name = op.getProperty().getValue();
-        name = name.toLowerCase();
-        Object value = op.getLiteral().getValue();
-        name = addPrefix( value, name );
-        stack.push( QueryBuilders.rangeQuery( name ).lte( value ));
+        final String name = op.getProperty().getValue().toLowerCase();
+        final Object value = op.getLiteral().getValue();
+
+
+        final RangeFilterBuilder termQuery =
+                FilterBuilders.rangeFilter( getFieldNameForType( value ) ).lte( sanitize( value ) );
+
+
+        queryBuilders.push( NoOpQueryBuilder.INSTANCE );
+
+        filterBuilders.push( fieldNameTerm( name, termQuery ) );
     }
 
 
     @Override
     public void visit( Equal op ) throws NoIndexException {
-        String name = op.getProperty().getValue();
-        name = name.toLowerCase();
-        Object value = op.getLiteral().getValue();
+        final String name = op.getProperty().getValue().toLowerCase();
+        final Object value = op.getLiteral().getValue();
 
+        //special case so we support our '*' char with wildcard
         if ( value instanceof String ) {
-            String svalue = (String)value;
+            final String svalue = ( String ) value;
 
-            BoolQueryBuilder qb = QueryBuilders.boolQuery();  // let's do a boolean OR
-            qb.minimumNumberShouldMatch(1);
+            final NestedQueryBuilder qb;  // let's do a boolean OR
 
-            // field is an entity/array that does not need a prefix on its name
-            // TODO is this right now that we've updated our doc structure?
-            // Should this be "must" instead of should?
-            qb = qb.should( QueryBuilders.wildcardQuery( name, svalue ) );
+            // or field is just a string that does need a prefix us a query
+            if ( svalue.indexOf( "*" ) != -1 ) {
 
-            // or field is just a string that does need a prefix
-            if ( svalue.indexOf("*") != -1 ) {
-                qb = qb.should( QueryBuilders.wildcardQuery( addPrefix( value, name ), svalue ) );
-            } else {
-                qb = qb.should( QueryBuilders.termQuery(     addPrefix( value, name ), value ));
+                final WildcardQueryBuilder wildcardQuery =
+                        QueryBuilders.wildcardQuery( IndexingUtils.FIELD_STRING_NESTED, svalue.toLowerCase() );
+                queryBuilders.push( fieldNameTerm( name, wildcardQuery ) );
+                filterBuilders.push( NoOpFilterBuilder.INSTANCE );
+                return;
             }
-            stack.push( qb );
+
+            //it's an exact match, use a filter
+            final TermFilterBuilder termFilter =
+                    FilterBuilders.termFilter( IndexingUtils.FIELD_STRING_EQUALS_NESTED, svalue.toLowerCase() );
+
+            queryBuilders.push( NoOpQueryBuilder.INSTANCE );
+            filterBuilders.push( fieldNameTerm( name, termFilter ) );
+
             return;
         }
 
         // assume all other types need prefix
-        stack.push( QueryBuilders.termQuery( addPrefix( value, name ), value ));
+
+        final TermFilterBuilder termQuery =
+                FilterBuilders.termFilter( getFieldNameForType( value ), sanitize( value ) );
+
+        filterBuilders.push( fieldNameTerm( name, termQuery ) );
+
+        queryBuilders.push( NoOpQueryBuilder.INSTANCE );
     }
 
 
     @Override
     public void visit( GreaterThan op ) throws NoIndexException {
-        String name = op.getProperty().getValue();
-        name = name.toLowerCase();
-        Object value = op.getLiteral().getValue();
-        name = addPrefix( value, name );
-        stack.push( QueryBuilders.rangeQuery( name ).gt( value ) );
+        final String name = op.getProperty().getValue().toLowerCase();
+        final Object value = op.getLiteral().getValue();
+
+
+        final RangeFilterBuilder rangeQuery =
+                FilterBuilders.rangeFilter( getFieldNameForType( value ) ).gt( sanitize( value ) );
+
+        filterBuilders.push( fieldNameTerm( name, rangeQuery ) );
+
+        queryBuilders.push( NoOpQueryBuilder.INSTANCE );
     }
 
 
     @Override
     public void visit( GreaterThanEqual op ) throws NoIndexException {
-        String name = op.getProperty().getValue();
-        name = name.toLowerCase();
+        String name = op.getProperty().getValue().toLowerCase();
         Object value = op.getLiteral().getValue();
-        name = addPrefix( value, name );
-        stack.push( QueryBuilders.rangeQuery( name ).gte( value ) );
+
+
+        final RangeFilterBuilder rangeQuery =
+                FilterBuilders.rangeFilter( getFieldNameForType( value ) ).gte( sanitize( value ) );
+
+        filterBuilders.push( fieldNameTerm( name, rangeQuery ) );
+
+        queryBuilders.push( NoOpQueryBuilder.INSTANCE );
     }
 
 
-    private String addPrefix( Object value, String origname ) {
-        return addPrefix(value, origname, false);
+    @Override
+    public Optional<FilterBuilder> getFilterBuilder() {
+        if ( filterBuilders.empty() ) {
+            return Optional.absent();
+        }
+
+        final FilterBuilder builder = filterBuilders.peek();
+
+        if ( !use( builder ) ) {
+            return Optional.absent();
+        }
+
+        return Optional.of( builder );
     }
 
 
-    private String addPrefix( Object value, String origname, boolean analyzed ) {
+    @Override
+    public Optional<QueryBuilder> getQueryBuilder() {
+        if ( queryBuilders.isEmpty() ) {
+            return Optional.absent();
+        }
 
-        String name = origname;
+        final QueryBuilder builder = queryBuilders.peek();
 
-        // logic to deal with nested property names
-        // only add prefix to last name in property
-        String[] parts = origname.split("\\.");
-        if ( parts.length > 1 ) {
-            name = parts[ parts.length - 1 ];
+        if ( !use( builder ) ) {
+            return Optional.absent();
         }
 
-        if ( value instanceof String && analyzed ) {
-            name = addAnalyzedStringPrefix( name );
 
-        } else if ( value instanceof String ) {
-            name = addStringPrefix( name );
+        return Optional.of( builder );
+    }
 
-        }else if ( value instanceof Integer ) {
-            name = addLongPrefix(name);
 
-        }else if ( value instanceof Long ) {
-            name = addLongPrefix(name);
 
-        } else if ( value instanceof Float ) {
-            name = addDoublePrefix(name);
+    /**
+     * Generate the field name term for the field name  for queries
+     */
+    private NestedQueryBuilder fieldNameTerm( final String fieldName, final QueryBuilder fieldValueQuery ) {
 
-        }else if ( value instanceof Float ) {
-            name = addDoublePrefix(name);
+        final BoolQueryBuilder booleanQuery = QueryBuilders.boolQuery();
 
-        } else if ( value instanceof Boolean ) {
-            name = addBooleanPrefix(name);
+        booleanQuery.must( QueryBuilders.termQuery( IndexingUtils.FIELD_NAME_NESTED, fieldName ) );
 
-        } else if ( value instanceof UUID ) {
-            name = addStringPrefix(name);
-        }
+        booleanQuery.must( fieldValueQuery );
 
-        // re-create nested property name
-        if ( parts.length > 1 ) {
-            parts[parts.length - 1] = name;
-            Joiner joiner = Joiner.on(".").skipNulls();
-            return joiner.join(parts);
-        }
 
-        return name;
+        return QueryBuilders.nestedQuery( IndexingUtils.ENTITY_FIELDS, booleanQuery );
     }
 
 
-    private String addAnalyzedStringPrefix( String name ) {
-      return name;
-    }
+    /**
+     * Generate the field name term for the field name for filters
+     */
+    private NestedFilterBuilder fieldNameTerm( final String fieldName, final FilterBuilder fieldValueBuilder ) {
 
+        final BoolFilterBuilder booleanQuery = FilterBuilders.boolFilter();
 
-    private String addStringPrefix( String name ) {
-        return name;
-    }
+        booleanQuery.must( FilterBuilders.termFilter( IndexingUtils.FIELD_NAME_NESTED, fieldName ) );
 
+        booleanQuery.must( fieldValueBuilder );
 
-    private String addDoublePrefix( String name ) {
-        return name;
-    }
 
-    private String addLongPrefix( String name ) {
-        return name;
+        return FilterBuilders.nestedFilter( IndexingUtils.ENTITY_FIELDS, booleanQuery );
     }
 
 
-    private String addBooleanPrefix( String name ) {
-        return name;
+    /**
+     * Get the field name for the primitive type
+     */
+    private String getFieldNameForType( final Object object ) {
+        if ( object instanceof String ) {
+            return IndexingUtils.FIELD_STRING_NESTED;
+        }
+
+        if ( object instanceof Boolean ) {
+            return IndexingUtils.FIELD_BOOLEAN_NESTED;
+        }
+
+
+        if ( object instanceof Integer || object instanceof Long ) {
+            return IndexingUtils.FIELD_LONG_NESTED;
+        }
+
+        if ( object instanceof Float || object instanceof Double ) {
+            return IndexingUtils.FIELD_DOUBLE_NESTED;
+        }
+
+
+        throw new UnsupportedOperationException(
+                "Unkown search type of " + object.getClass().getName() + " encountered" );
     }
 
 
-    @Override
-    public Optional<QueryBuilder> getQueryBuilder() {
-//        if ( stack.isEmpty() ) {
-            return Optional.absent();
-//        }
-//        return stack.pop();
+    /**
+     * Lowercase our input
+     */
+    private Object sanitize( final Object input ) {
+        if ( input instanceof String ) {
+            return ( ( String ) input ).toLowerCase();
+        }
 
+        return input;
+    }
 
+
+    /**
+     * Return false if our element is a no-op, true otherwise
+     */
+    private boolean use( final QueryBuilder queryBuilder ) {
+        return queryBuilder != NoOpQueryBuilder.INSTANCE;
     }
 
 
-    @Override
-	public Optional<FilterBuilder> getFilterBuilder() {
-        return Optional.absent();
-//
-//		if ( filterBuilders.size() >  1 ) {
-//
-//			FilterBuilder andFilter = null;
-//			for ( FilterBuilder fb : filterBuilders ) {
-//				if ( andFilter == null ) {
-//					andFilter = FilterBuilders.andFilter( fb );
-//				} else {
-//					andFilter = FilterBuilders.andFilter( andFilter, fb );
-//				}
-//			}
-//
-//		} else if ( !filterBuilders.isEmpty() ) {
-//			return filterBuilders.get(0);
-//		}
-//		return null;
-	}
+    /**
+     * Return false if our element is a no-op, true otherwise
+     */
+    private boolean use( final FilterBuilder filterBuilder ) {
+        return filterBuilder != NoOpFilterBuilder.INSTANCE;
+    }
 
 
     @Override
-    public Collection<String> getGeoSelectFields() {
-        return Collections.EMPTY_LIST;
+    public Set<String> getGeoSelectFields() {
+        return geoFields;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexEdgeImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexEdgeImpl.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexEdgeImpl.java
index 8b66c85..c3e7c9d 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexEdgeImpl.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexEdgeImpl.java
@@ -33,7 +33,7 @@ import org.apache.usergrid.persistence.model.entity.Id;
  */
 public class IndexEdgeImpl extends SearchEdgeImpl implements IndexEdge {
 
-    private final long timestamp;
+    protected final long timestamp;
 
 
     public IndexEdgeImpl( final Id nodeId, final String name, final NodeType nodeType, final long timestamp ) {
@@ -46,4 +46,39 @@ public class IndexEdgeImpl extends SearchEdgeImpl implements IndexEdge {
     public long getTimestamp() {
         return timestamp;
     }
+
+
+    @Override
+    public boolean equals( final Object o ) {
+        if ( this == o ) {
+            return true;
+        }
+        if ( !( o instanceof IndexEdgeImpl ) ) {
+            return false;
+        }
+        if ( !super.equals( o ) ) {
+            return false;
+        }
+
+        final IndexEdgeImpl indexEdge = ( IndexEdgeImpl ) o;
+
+        return timestamp == indexEdge.timestamp;
+    }
+
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        result = 31 * result + ( int ) ( timestamp ^ ( timestamp >>> 32 ) );
+        return result;
+    }
+
+
+    @Override
+    public String toString() {
+        return "IndexEdgeImpl{" +
+                "timestamp=" + timestamp +
+                "} " + super.toString();
+    }
 }
+

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexingUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexingUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexingUtils.java
index de1bfd9..99c3914 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexingUtils.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexingUtils.java
@@ -69,31 +69,34 @@ public class IndexingUtils {
 
     /**
      * Reserved field types in our document
+     *
+     * We use longs for ints, and doubles for floats to avoid runtime type conflicts
      */
     public static final String FIELD_NAME = "name";
     public static final String FIELD_BOOLEAN = "boolean";
-    public static final String FIELD_INT = "int";
     public static final String FIELD_LONG = "long";
-    public static final String FIELD_FLOAT = "float";
     public static final String FIELD_DOUBLE = "double";
     public static final String FIELD_LOCATION = "location";
     public static final String FIELD_STRING = "string";
 
 
+
+
+
     /**
-     * All possible sort values
+     * All search/sort values
      */
-    public static final String SORT_FIELD_BOOLEAN = ENTITY_FIELDS + ".boolean";
-    public static final String SORT_FIELD_INT = ENTITY_FIELDS + ".int";
-    public static final String SORT_FIELD_LONG = ENTITY_FIELDS + ".long";
-    public static final String SORT_FIELD_FLOAT = ENTITY_FIELDS + ".float";
-    public static final String SORT_FIELD_DOUBLE = ENTITY_FIELDS + ".double";
-    public static final String SORT_FIELD_LOCATION = ENTITY_FIELDS + ".location";
-    public static final String SORT_FIELD_STRING = ENTITY_FIELDS + ".string";
+    public static final String FIELD_NAME_NESTED = ENTITY_FIELDS + "." + FIELD_NAME;
+    public static final String FIELD_BOOLEAN_NESTED = ENTITY_FIELDS + "." + FIELD_BOOLEAN;
+    public static final String FIELD_LONG_NESTED = ENTITY_FIELDS + "." + FIELD_LONG;
+    public static final String FIELD_DOUBLE_NESTED = ENTITY_FIELDS + "." + FIELD_DOUBLE;
+    public static final String SORT_FIELD_LOCATION = ENTITY_FIELDS + "." + FIELD_LOCATION;
+    public static final String FIELD_STRING_NESTED = ENTITY_FIELDS + "." + FIELD_STRING;
+    public static final String FIELD_STRING_EQUALS_NESTED = FIELD_STRING_NESTED + ".exact";
+
+
 
 
-    //The value appended to the string field when it's an exact match.  Should only be used on search, never index
-    public static final String FIELD_STRING_EQUALS = FIELD_STRING + ".exact";
 
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/NoOpFilterBuilder.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/NoOpFilterBuilder.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/NoOpFilterBuilder.java
new file mode 100644
index 0000000..9d3c95c
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/NoOpFilterBuilder.java
@@ -0,0 +1,45 @@
+/*
+ *
+ *  *
+ *  * 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.
+ *  *
+ *
+ */
+
+package org.apache.usergrid.persistence.index.impl;
+
+
+import java.io.IOException;
+
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.index.query.BaseFilterBuilder;
+
+
+/**
+ * Marker interface that does nothing
+ */
+public class NoOpFilterBuilder extends BaseFilterBuilder {
+
+    public static final NoOpFilterBuilder INSTANCE = new NoOpFilterBuilder();
+
+
+    @Override
+    protected void doXContent( final XContentBuilder builder, final Params params ) throws IOException {
+        //no op
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/NoOpQueryBuilder.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/NoOpQueryBuilder.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/NoOpQueryBuilder.java
new file mode 100644
index 0000000..acad20c
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/NoOpQueryBuilder.java
@@ -0,0 +1,45 @@
+/*
+ *
+ *  *
+ *  * 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.
+ *  *
+ *
+ */
+
+package org.apache.usergrid.persistence.index.impl;
+
+
+import java.io.IOException;
+
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.index.query.BaseQueryBuilder;
+import org.elasticsearch.index.query.QueryBuilder;
+
+
+/**
+ * Marker interface that does nothing
+ */
+public class NoOpQueryBuilder extends BaseQueryBuilder implements QueryBuilder {
+
+    public static final NoOpQueryBuilder INSTANCE = new NoOpQueryBuilder();
+
+    @Override
+    protected void doXContent( final XContentBuilder builder, final Params params ) throws IOException {
+         //no op
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/SearchEdgeImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/SearchEdgeImpl.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/SearchEdgeImpl.java
index 1813017..b401102 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/SearchEdgeImpl.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/SearchEdgeImpl.java
@@ -27,9 +27,9 @@ import org.apache.usergrid.persistence.model.entity.Id;
  * will be on the opposite side of the edge from the specified nodeId
  */
 public class SearchEdgeImpl implements SearchEdge {
-    private final Id nodeId;
-    private final String name;
-    private final NodeType nodeType;
+    protected final Id nodeId;
+    protected final String name;
+    protected final NodeType nodeType;
 
 
     public SearchEdgeImpl( final Id nodeId, final String name, final NodeType nodeType ) {
@@ -55,4 +55,44 @@ public class SearchEdgeImpl implements SearchEdge {
     public NodeType getNodeType() {
         return nodeType;
     }
+
+
+    @Override
+    public boolean equals( final Object o ) {
+        if ( this == o ) {
+            return true;
+        }
+        if ( !( o instanceof SearchEdgeImpl ) ) {
+            return false;
+        }
+
+        final SearchEdgeImpl that = ( SearchEdgeImpl ) o;
+
+        if ( !nodeId.equals( that.nodeId ) ) {
+            return false;
+        }
+        if ( !name.equals( that.name ) ) {
+            return false;
+        }
+        return nodeType == that.nodeType;
+    }
+
+
+    @Override
+    public int hashCode() {
+        int result = nodeId.hashCode();
+        result = 31 * result + name.hashCode();
+        result = 31 * result + nodeType.hashCode();
+        return result;
+    }
+
+
+    @Override
+    public String toString() {
+        return "SearchEdgeImpl{" +
+                "nodeId=" + nodeId +
+                ", name='" + name + '\'' +
+                ", nodeType=" + nodeType +
+                '}';
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/SearchRequestBuilderStrategy.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/SearchRequestBuilderStrategy.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/SearchRequestBuilderStrategy.java
index fa82ad6..49be2e9 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/SearchRequestBuilderStrategy.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/SearchRequestBuilderStrategy.java
@@ -21,6 +21,7 @@ package org.apache.usergrid.persistence.index.impl;
 
 
 import org.elasticsearch.action.search.SearchRequestBuilder;
+import org.elasticsearch.index.query.BoolFilterBuilder;
 import org.elasticsearch.index.query.BoolQueryBuilder;
 import org.elasticsearch.index.query.FilterBuilder;
 import org.elasticsearch.index.query.FilterBuilders;
@@ -87,14 +88,14 @@ public class SearchRequestBuilderStrategy {
 
         final QueryVisitor visitor = visitParsedQuery( query );
 
-        srb.setQuery( createQueryBuilder( searchEdge, visitor, searchTypes ) );
+        final Optional<QueryBuilder> queryBuilder = visitor.getQueryBuilder();
 
-        final Optional<FilterBuilder> fb = visitor.getFilterBuilder();
-
-        if ( fb.isPresent() ) {
-            srb.setPostFilter( fb.get() );
+        if(queryBuilder.isPresent()){
+          srb.setQuery( queryBuilder.get() );
         }
 
+        srb.setPostFilter(createFilterBuilder( searchEdge, visitor, searchTypes ) );
+
 
         srb = srb.setFrom( 0 ).setSize( limit );
 
@@ -120,26 +121,24 @@ public class SearchRequestBuilderStrategy {
             final String propertyName = sp.getPropertyName();
 
 
-            srb.addSort( createSort( order, IndexingUtils.SORT_FIELD_STRING, propertyName ) );
-
+            srb.addSort( createSort( order, IndexingUtils.FIELD_STRING_NESTED, propertyName ) );
 
-            srb.addSort( createSort( order, IndexingUtils.SORT_FIELD_INT, propertyName ) );
 
-            srb.addSort( createSort( order, IndexingUtils.SORT_FIELD_DOUBLE, propertyName ) );
+            srb.addSort( createSort( order, IndexingUtils.FIELD_DOUBLE_NESTED, propertyName ) );
 
-            srb.addSort( createSort( order, IndexingUtils.SORT_FIELD_BOOLEAN, propertyName ) );
+            srb.addSort( createSort( order, IndexingUtils.FIELD_BOOLEAN_NESTED, propertyName ) );
 
 
-            srb.addSort( createSort( order, IndexingUtils.SORT_FIELD_LONG, propertyName ) );
+            srb.addSort( createSort( order, IndexingUtils.FIELD_LONG_NESTED, propertyName ) );
 
-            srb.addSort( createSort( order, IndexingUtils.SORT_FIELD_FLOAT, propertyName ) );
         }
         return srb;
     }
 
 
-    public QueryBuilder createQueryBuilder( final SearchEdge searchEdge, final QueryVisitor visitor,
-                                            final SearchTypes searchTypes ) {
+
+    public BoolFilterBuilder createFilterBuilder( final SearchEdge searchEdge, final QueryVisitor visitor,
+                                                  final SearchTypes searchTypes ) {
         String context = createContextName( applicationScope, searchEdge );
 
 
@@ -151,29 +150,36 @@ public class SearchRequestBuilderStrategy {
         // Do we need to put the context term first for performance?
 
         //make sure we have entity in the context
-        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
+        BoolFilterBuilder boolQueryFilter = FilterBuilders.boolFilter();
 
-        boolQueryBuilder.must( QueryBuilders.termQuery( IndexingUtils.EDGE_SEARCH_FIELDNAME, context ) );
+        //add our edge search
+        boolQueryFilter.must( FilterBuilders.termFilter( IndexingUtils.EDGE_SEARCH_FIELDNAME, context ) );
 
 
         /**
-         * Get the scopes and add them
+         * For the types the user specified, add them to an OR so 1 of them must match
          */
+        final String[] sourceTypes = searchTypes.getTypeNames( applicationScope );
 
 
-        final String[] sourceTypes = searchTypes.getTypeNames( applicationScope );
+        final FilterBuilder[] typeTerms = new FilterBuilder[sourceTypes.length];
+
+        for(int i = 0; i < sourceTypes.length; i ++){
+            typeTerms[i] = FilterBuilders.termFilter(  IndexingUtils.ENTITY_TYPE_FIELDNAME, sourceTypes[i]  );
+        }
 
         //add all our types, 1 type must match per query
-        boolQueryBuilder.must( QueryBuilders.termsQuery( IndexingUtils.ENTITY_TYPE_FIELDNAME, sourceTypes )
-                                            .minimumMatch( 1 ) );
+        boolQueryFilter.must( FilterBuilders.orFilter( typeTerms ) );
+
+        //if we have a filter from our visitor, add it
 
-        Optional<QueryBuilder> queryBuilder = visitor.getQueryBuilder();
+        Optional<FilterBuilder> queryBuilder = visitor.getFilterBuilder();
 
         if ( queryBuilder.isPresent() ) {
-            boolQueryBuilder.must( queryBuilder.get() );
+            boolQueryFilter.must( queryBuilder.get() );
         }
 
-        return boolQueryBuilder;
+        return boolQueryFilter;
     }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/query/ParsedQueryBuilder.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/query/ParsedQueryBuilder.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/query/ParsedQueryBuilder.java
index 3498f3c..aa279fc 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/query/ParsedQueryBuilder.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/query/ParsedQueryBuilder.java
@@ -73,7 +73,7 @@ public class ParsedQueryBuilder {
 
             //junk, bail
             else {
-               outputQuery = "select * where" + trimmedLowercaseQuery;
+               outputQuery = "select * where " + trimmedLowercaseQuery;
             }
         }
         else {

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/query/tree/QueryVisitor.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/query/tree/QueryVisitor.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/query/tree/QueryVisitor.java
index 42d6d3a..3fb0777 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/query/tree/QueryVisitor.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/query/tree/QueryVisitor.java
@@ -20,6 +20,7 @@ package org.apache.usergrid.persistence.index.query.tree;
 
 
 import java.util.Collection;
+import java.util.Set;
 
 import org.apache.usergrid.persistence.index.exceptions.NoFullTextIndexException;
 import org.apache.usergrid.persistence.index.exceptions.NoIndexException;
@@ -99,11 +100,6 @@ public interface QueryVisitor {
      */
     void visit( GreaterThanEqual op ) throws NoIndexException;
 
-    /** 
-     * Returns resulting query builder.
-     */
-    Optional<QueryBuilder> getQueryBuilder();
-
 
     /**
      * Return any filters created during parsing
@@ -111,11 +107,19 @@ public interface QueryVisitor {
      */
 	Optional<FilterBuilder> getFilterBuilder();
 
+
+
+    /**
+     * Return any querybuilders
+     * @return
+     */
+	Optional<QueryBuilder> getQueryBuilder();
+
     /**
      * Some searches, such as geo have a side effect of adding a geo sort.  Get any sorts that are side effects
      * of the query terms, in the order they should be applied.  Note that user specified sort orders will trump
      * these sorts
      * @return
      */
-    Collection<String> getGeoSelectFields();
+    Set<String> getGeoSelectFields();
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/main/resources/org/apache/usergrid/persistence/index/usergrid-mappings.json
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/resources/org/apache/usergrid/persistence/index/usergrid-mappings.json b/stack/corepersistence/queryindex/src/main/resources/org/apache/usergrid/persistence/index/usergrid-mappings.json
index aac82b8..e90f5a7 100644
--- a/stack/corepersistence/queryindex/src/main/resources/org/apache/usergrid/persistence/index/usergrid-mappings.json
+++ b/stack/corepersistence/queryindex/src/main/resources/org/apache/usergrid/persistence/index/usergrid-mappings.json
@@ -57,18 +57,10 @@
             "type": "boolean",
             "doc_values": true
           },
-          "int": {
-            "type": "integer",
-            "doc_values": true
-          },
           "long": {
             "type": "long",
             "doc_values": true
           },
-          "float": {
-            "type": "float",
-            "doc_values": true
-          },
           "double": {
             "type": "double",
             "doc_values": true

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverterTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverterTest.java b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverterTest.java
index 020fad6..002e9b2 100644
--- a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverterTest.java
+++ b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverterTest.java
@@ -145,7 +145,7 @@ public class EntityToMapConverterTest {
     @Test
     public void testIntegerField() {
         testSingleField( new IntegerField( "name", 100 ),
-                ( field, entityField ) -> assertEquals( field.getValue(), entityField.get( IndexingUtils.FIELD_INT )
+                ( field, entityField ) -> assertEquals( field.getValue(), entityField.get( IndexingUtils.FIELD_LONG )
                                                       ) );
     }
 
@@ -160,7 +160,7 @@ public class EntityToMapConverterTest {
     @Test
     public void testFloadField() {
         testSingleField( new FloatField( "name", 1.10f ), ( field, entityField ) -> assertEquals( field.getValue(),
-                        entityField.get( IndexingUtils.FIELD_FLOAT ) ) );
+                        entityField.get( IndexingUtils.FIELD_DOUBLE ) ) );
     }
 
 
@@ -258,7 +258,7 @@ public class EntityToMapConverterTest {
         array.add( 2 );
         array.add( 3 );
 
-        testPrimitiveArray( array, IndexingUtils.FIELD_INT );
+        testPrimitiveArray( array, IndexingUtils.FIELD_LONG );
     }
 
 
@@ -286,7 +286,7 @@ public class EntityToMapConverterTest {
         array.add( 2.0f );
         array.add( 3.0f );
 
-        testPrimitiveArray( array, IndexingUtils.FIELD_FLOAT );
+        testPrimitiveArray( array, IndexingUtils.FIELD_DOUBLE );
     }
 
 
@@ -363,7 +363,7 @@ public class EntityToMapConverterTest {
     @Test
     public void testIntegerFieldSubObject() {
         testNestedField( new IntegerField( "name", 100 ),
-                ( field, entityField ) -> assertEquals( field.getValue(), entityField.get( IndexingUtils.FIELD_INT )
+                ( field, entityField ) -> assertEquals( field.getValue(), entityField.get( IndexingUtils.FIELD_LONG )
                                                       ) );
     }
 
@@ -378,7 +378,7 @@ public class EntityToMapConverterTest {
     @Test
     public void testFloadFieldSubObject() {
         testNestedField( new FloatField( "name", 1.10f ), ( field, entityField ) -> assertEquals( field.getValue(),
-                entityField.get( IndexingUtils.FIELD_FLOAT ) ) );
+                entityField.get( IndexingUtils.FIELD_DOUBLE ) ) );
     }
 
 
@@ -480,7 +480,7 @@ public class EntityToMapConverterTest {
     @Test
     public void testIntegerFieldSubObjectArray() {
         testNestedFieldArraySubObject( new IntegerField( "name", 100 ),
-                ( field, entityField ) -> assertEquals( field.getValue(), entityField.get( IndexingUtils.FIELD_INT )
+                ( field, entityField ) -> assertEquals( field.getValue(), entityField.get( IndexingUtils.FIELD_LONG )
                                                       ) );
     }
 
@@ -497,7 +497,7 @@ public class EntityToMapConverterTest {
     public void testFloadFieldSubObjectArray() {
         testNestedFieldArraySubObject( new FloatField( "name", 1.10f ),
                 ( field, entityField ) -> assertEquals( field.getValue(),
-                        entityField.get( IndexingUtils.FIELD_FLOAT ) ) );
+                        entityField.get( IndexingUtils.FIELD_DOUBLE ) ) );
     }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/test/resources/log4j.properties b/stack/corepersistence/queryindex/src/test/resources/log4j.properties
index 1dc4831..c66b139 100644
--- a/stack/corepersistence/queryindex/src/test/resources/log4j.properties
+++ b/stack/corepersistence/queryindex/src/test/resources/log4j.properties
@@ -36,5 +36,10 @@ log4j.appender.stdout.layout.ConversionPattern=%d %p (%t) %c{1} - %m%n
 
 #log4j.logger.org.apache.cassandra.service.StorageProxy=DEBUG, stdout
 
+#Debug our queries
 log4j.logger.org.apache.usergrid.persistence.index.impl.EsApplicationEntityIndexImpl=DEBUG
+#Debug our writes
+log4j.logger.org.apache.usergrid.persistence.index.impl.EsIndexBufferConsumerImpl=DEBUG
+#Batch debugging
+log4j.logger.org.apache.usergrid.persistence.index.impl.EsEntityIndexBatchImpl=DEBUG
 log4j.logger.org.apache.usergrid=INFO

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/96555347/stack/corepersistence/queryindex/src/test/resources/test.json
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/test/resources/test.json b/stack/corepersistence/queryindex/src/test/resources/test.json
new file mode 100644
index 0000000..b13c153
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/test/resources/test.json
@@ -0,0 +1,133 @@
+{
+  "entityVersion": "f6928d60-dd71-11e4-8fcf-c6c6eebe8d56",
+  "edgeNodeId": "f64f69cc-dd71-11e4-8fcf-c6c6eebe8d56_application",
+  "edgeName": "things",
+  "entityType": "f64f69cc-dd71-11e4-8fcf-c6c6eebe8d56_application__thing",
+  "edgeType": "SOURCE",
+  "edgeTimestamp": 1,
+  "edgeSearch": "f64f69cc-dd71-11e4-8fcf-c6c6eebe8d56_application__f64f69cc-dd71-11e4-8fcf-c6c6eebe8d56_application__things__SOURCE",
+  "entityId": "f6928d5f-dd71-11e4-8fcf-c6c6eebe8d56_thing",
+  "applicationId": "f64f69cc-dd71-11e4-8fcf-c6c6eebe8d56_application",
+  "fields": [
+    {
+      "name": "gender",
+      "string": "female"
+    },
+    {
+      "name": "latitude",
+      "double": 47.3984
+    },
+    {
+      "name": "about",
+      "string": "cupidatat est elit fugiat eu non lorem ea sunt eu lorem. lorem elit commodo pariatur labore velit cillum id officia anim aliquip. proident sunt consectetur laborum ullamco nisi excepteur sit laborum. id cillum nulla esse eiusmod non exercitation deserunt incididunt eu cupidatat sit proident labore. do dolor culpa sunt esse esse voluptate minim eiusmod in deserunt incididunt.\r\n"
+    },
+    {
+      "name": "registered",
+      "string": "1994-06-05t10:31:45 +04:00"
+    },
+    {
+      "name": "isActive",
+      "boolean": true
+    },
+    {
+      "name": "picture",
+      "string": "http://placehold.it/32x32"
+    },
+    {
+      "name": "friends.name",
+      "string": "boyle davis"
+    },
+    {
+      "name": "friends.id",
+      "int": 0
+    },
+    {
+      "name": "friends.name",
+      "string": "cassandra morales"
+    },
+    {
+      "name": "friends.id",
+      "int": 1
+    },
+    {
+      "name": "friends.name",
+      "string": "jolene olson"
+    },
+    {
+      "name": "friends.id",
+      "int": 2
+    },
+    {
+      "name": "tags",
+      "string": "aliquip"
+    },
+    {
+      "name": "tags",
+      "string": "voluptate"
+    },
+    {
+      "name": "tags",
+      "string": "nostrud"
+    },
+    {
+      "name": "tags",
+      "string": "ullamco"
+    },
+    {
+      "name": "tags",
+      "string": "deserunt"
+    },
+    {
+      "name": "tags",
+      "string": "quis"
+    },
+    {
+      "name": "tags",
+      "string": "qui"
+    },
+    {
+      "name": "balance",
+      "string": "$3,498.00"
+    },
+    {
+      "name": "randomArrayItem",
+      "string": "cherry"
+    },
+    {
+      "name": "contact.address",
+      "string": "843 bath avenue, sanders, alabama, 7969"
+    },
+    {
+      "name": "contact.phone",
+      "string": "+1 (846) 498-2864"
+    },
+    {
+      "name": "contact.email",
+      "string": "minervaharrell@isis.com"
+    },
+    {
+      "name": "name",
+      "string": "minerva harrell"
+    },
+    {
+      "name": "guid",
+      "string": "e377f195-58c7-46d1-b9ff-28fd0391e222"
+    },
+    {
+      "name": "company",
+      "string": "isis"
+    },
+    {
+      "name": "id",
+      "int": 9
+    },
+    {
+      "name": "age",
+      "int": 40
+    },
+    {
+      "name": "longitude",
+      "double": -81.830573
+    }
+  ]
+}


Mime
View raw message