Repository: usergrid
Updated Branches:
  refs/heads/USERGRID-926 [created] 5cc0b3807


add distance field


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

Branch: refs/heads/USERGRID-926
Commit: a9da97df7669caea605529e83943a9846aea3f40
Parents: a7b6a9c
Author: Shawn Feldman <[email protected]>
Authored: Fri Nov 6 11:10:45 2015 -0700
Committer: Shawn Feldman <[email protected]>
Committed: Fri Nov 6 11:10:45 2015 -0700

----------------------------------------------------------------------
 .../read/search/CandidateEntityFilter.java      |  6 +++
 .../org/apache/usergrid/persistence/GeoIT.java  | 42 ++++++++++++++++++++
 .../model/entity/EntityToMapConverter.java      |  8 +++-
 .../persistence/model/field/DistanceField.java  | 42 ++++++++++++++++++++
 .../persistence/model/field/FieldTypeName.java  |  3 +-
 .../persistence/index/GeoCandidateResult.java   | 40 +++++++++++++++++++
 .../index/impl/EsEntityIndexImpl.java           |  7 ++--
 .../persistence/index/impl/IndexingUtils.java   | 39 +++++++++++++-----
 8 files changed, 172 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/usergrid/blob/a9da97df/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/CandidateEntityFilter.java
----------------------------------------------------------------------
diff --git 
a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/CandidateEntityFilter.java
 
b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/CandidateEntityFilter.java
index 9a9636f..449639c 100644
--- 
a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/CandidateEntityFilter.java
+++ 
b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/CandidateEntityFilter.java
@@ -25,6 +25,8 @@ import java.util.*;
 import org.apache.usergrid.corepersistence.index.IndexLocationStrategyFactory;
 import org.apache.usergrid.persistence.index.*;
 import org.apache.usergrid.persistence.index.impl.IndexProducer;
+import org.apache.usergrid.persistence.model.field.DistanceField;
+import org.apache.usergrid.persistence.model.field.DoubleField;
 import org.apache.usergrid.persistence.model.field.Field;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -197,6 +199,7 @@ public class CandidateEntityFilter extends 
AbstractFilter<FilterResult<Candidate
 
             final Candidate candidate = filterResult.getValue();
             final CandidateResult candidateResult = 
candidate.getCandidateResult();
+            final boolean isGeo = candidateResult instanceof 
GeoCandidateResult;
             final SearchEdge searchEdge = candidate.getSearchEdge();
             final Id candidateId = candidateResult.getId();
             final UUID candidateVersion = candidateResult.getVersion();
@@ -252,6 +255,9 @@ public class CandidateEntityFilter extends 
AbstractFilter<FilterResult<Candidate
             //they're the same add it
 
             final Entity returnEntity = entity.getEntity().get();
+            if(isGeo){
+                returnEntity.setField(new 
DistanceField(((GeoCandidateResult)candidateResult).getDistance()));
+            }
 
             final Optional<EdgePath> parent = filterResult.getPath();
 

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a9da97df/stack/core/src/test/java/org/apache/usergrid/persistence/GeoIT.java
----------------------------------------------------------------------
diff --git 
a/stack/core/src/test/java/org/apache/usergrid/persistence/GeoIT.java 
b/stack/core/src/test/java/org/apache/usergrid/persistence/GeoIT.java
index 230f9be..fcc4c32 100644
--- a/stack/core/src/test/java/org/apache/usergrid/persistence/GeoIT.java
+++ b/stack/core/src/test/java/org/apache/usergrid/persistence/GeoIT.java
@@ -161,6 +161,48 @@ public class GeoIT extends AbstractCoreIT {
         em.delete(user);
     }
 
+
+    /**
+     * Validate the ability to query a moving entity
+     * 1. Create an entity with location
+     * 2. Query from a point near the entity's location
+     * 3. Move the entity farther away from the center point
+     * 4. Run the same query again to verify the entity is no longer in the 
area
+     */
+    @Test
+    public void validateDistanceQueryExists() throws Exception {
+        LOG.info("GeoIT.testMovingTarget");
+        //Get the EntityManager instance
+        EntityManager em = app.getEntityManager();
+        assertNotNull(em);
+
+        //1. Create an entity with location
+        Map<String, Object> properties = new LinkedHashMap<String, Object>() {{
+            put("username", "edanuff");
+            put("email", "[email protected]");
+            put("location", new LinkedHashMap<String, Object>() {{
+                put("latitude", 37.776753);
+                put("longitude", -122.407846);
+            }});
+        }};
+        Entity user = em.create("user", properties);
+        assertNotNull(user);
+        app.refreshIndex();
+
+        final double lat = 37.776753;
+        final double lon = -122.407846;
+        //2. Query from a point near the entity's location
+        Query query = Query.fromQL("select * where location within 100 of "
+            + lat + "," + lon);
+        Results listResults = em.searchCollection(em.getApplicationRef(), 
"users", query);
+        assertEquals(1, listResults.size());
+        Entity entity = listResults.getEntity();
+        assertTrue(entity.getMetadata("distance")!=null);
+        assertTrue(Double.parseDouble( 
entity.getMetadata("distance").toString())>0);
+
+        em.delete(user);
+    }
+
     /**
      * Validate the ability to query connections within proximity of the users
      * 1. Create an entity with location

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a9da97df/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/entity/EntityToMapConverter.java
----------------------------------------------------------------------
diff --git 
a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/entity/EntityToMapConverter.java
 
b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/entity/EntityToMapConverter.java
index b9f637a..dd7a916 100644
--- 
a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/entity/EntityToMapConverter.java
+++ 
b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/entity/EntityToMapConverter.java
@@ -57,8 +57,14 @@ public class EntityToMapConverter {
     }
 
     private EntityMap toMap( EntityObject entity, EntityMap entityMap ) {
+
         for ( Field field : entity.getFields() ) {
-            if ( field instanceof ListField || field instanceof ArrayField  || 
field instanceof SetField) {
+            if( field instanceof DistanceField){
+                
if(!entityMap.containsKey("metadata"))entityMap.put("metadata",new 
HashMap<String,Object>());
+                DistanceField distanceField = (DistanceField) field;
+                Map<String,Object> metaMap = (Map) entityMap.get("metadata");
+                metaMap.put(DistanceField.NAME, distanceField.getValue());
+            }else if ( field instanceof ListField || field instanceof 
ArrayField  || field instanceof SetField) {
                 Collection list = ( Collection ) field.getValue();
                 entityMap.put( field.getName(), processCollection( list )  );
             }

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a9da97df/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/DistanceField.java
----------------------------------------------------------------------
diff --git 
a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/DistanceField.java
 
b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/DistanceField.java
new file mode 100644
index 0000000..4e9e1e1
--- /dev/null
+++ 
b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/DistanceField.java
@@ -0,0 +1,42 @@
+/*
+ *
+ *  * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  *  contributor license agreements.  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.  For additional information regarding
+ *  * copyright in this work, please see the NOTICE file in the top level
+ *  * directory of this distribution.
+ *
+ */
+package org.apache.usergrid.persistence.model.field;
+
+/**
+ * Classy class class.
+ */
+public class DistanceField extends DoubleField {
+    public static final String NAME = "distance";
+    public DistanceField( Double value) {
+        super(NAME, value);
+    }
+
+    public DistanceField( Double value, boolean unique) {
+        super(NAME, value, unique);
+    }
+
+    public DistanceField() {
+        super();
+    }
+    @Override
+    public FieldTypeName getTypeName() {
+        return FieldTypeName.DISTANCE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a9da97df/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/FieldTypeName.java
----------------------------------------------------------------------
diff --git 
a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/FieldTypeName.java
 
b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/FieldTypeName.java
index 90f3879..8b0cdc3 100644
--- 
a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/FieldTypeName.java
+++ 
b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/FieldTypeName.java
@@ -39,5 +39,6 @@ public enum FieldTypeName {
     LONG,
     SET,
     STRING,
-    UUID
+    UUID,
+    DISTANCE
 }

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a9da97df/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/GeoCandidateResult.java
----------------------------------------------------------------------
diff --git 
a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/GeoCandidateResult.java
 
b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/GeoCandidateResult.java
new file mode 100644
index 0000000..07ef41c
--- /dev/null
+++ 
b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/GeoCandidateResult.java
@@ -0,0 +1,40 @@
+/*
+ *
+ *  * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  *  contributor license agreements.  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.  For additional information regarding
+ *  * copyright in this work, please see the NOTICE file in the top level
+ *  * directory of this distribution.
+ *
+ */
+package org.apache.usergrid.persistence.index;
+
+import org.apache.usergrid.persistence.model.entity.Id;
+
+import java.util.UUID;
+
+/**
+ * Classy class class.
+ */
+public class GeoCandidateResult extends CandidateResult {
+    private final double distance;
+
+    public GeoCandidateResult(Id entityId, UUID entityVersion, String docId, 
double distance) {
+        super(entityId, entityVersion, docId);
+        this.distance = distance;
+    }
+
+    public double getDistance() {
+        return distance;
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a9da97df/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java
----------------------------------------------------------------------
diff --git 
a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java
 
b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java
index f03a98a..b32a11c 100644
--- 
a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java
+++ 
b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java
@@ -668,11 +668,12 @@ public class EsEntityIndexImpl implements 
EntityIndex,VersionedData {
         logger.debug( "   Hit count: {} Total hits: {}", hits.length, 
searchHits.getTotalHits() );
 
         List<CandidateResult> candidates = new ArrayList<>( hits.length );
+        final boolean isGeo = query.getOriginalQuery().contains("location") && 
query.getOriginalQuery().contains("within");
 
         for ( SearchHit hit : hits ) {
+            CandidateResult candidateResult;
 
-            final CandidateResult candidateResult = parseIndexDocId( 
hit.getId() );
-
+            candidateResult =  parseIndexDocId( hit, isGeo );
             candidates.add( candidateResult );
         }
 
@@ -696,7 +697,7 @@ public class EsEntityIndexImpl implements 
EntityIndex,VersionedData {
 
         for ( SearchHit hit : hits ) {
 
-            final CandidateResult candidateResult = parseIndexDocId( 
hit.getId() );
+            final CandidateResult candidateResult = parseIndexDocId( hit );
 
             // if comparing against the latestVersion, make sure we only add 
the candidateResult if it's
             // older than or equal to the latest marked version

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a9da97df/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 18cb928..88da04e 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
@@ -24,6 +24,7 @@ import java.util.regex.Pattern;
 
 import org.apache.usergrid.persistence.core.scope.ApplicationScope;
 import org.apache.usergrid.persistence.index.CandidateResult;
+import org.apache.usergrid.persistence.index.GeoCandidateResult;
 import org.apache.usergrid.persistence.index.IndexEdge;
 import org.apache.usergrid.persistence.index.SearchEdge;
 import org.apache.usergrid.persistence.model.entity.Entity;
@@ -31,6 +32,7 @@ import org.apache.usergrid.persistence.model.entity.Id;
 import org.apache.usergrid.persistence.model.entity.SimpleId;
 
 import com.google.common.base.Preconditions;
+import org.elasticsearch.search.SearchHit;
 
 
 public class IndexingUtils {
@@ -220,28 +222,45 @@ public class IndexingUtils {
         builder.append( type ).append( "(" ).append( value ).append( ")" );
     }
 
-
     /**
      * Parse the document id into a candidate result
      */
-    public static CandidateResult parseIndexDocId( final String documentId ) {
+    public static CandidateResult parseIndexDocId( final SearchHit hit ) {
+        return parseIndexDocId(hit.getId());
+    }
+
+    public static CandidateResult parseIndexDocId( final SearchHit hit, 
boolean isGeo ) {
 
+        final String documentId = hit.getId();
+        final double distance = isGeo ? (double) hit.sortValues()[0] : -1;
+        return parseIndexDocId(documentId,distance);
+    }
+
+    public static CandidateResult parseIndexDocId( final String documentId ) {
+        return parseIndexDocId(documentId,-1);
+    }
+        /**
+         * Parse the document id into a candidate result
+         */
+    public static CandidateResult parseIndexDocId( final String documentId, 
final double distance ) {
 
-        final Matcher matcher = DOCUMENT_PATTERN.matcher( documentId );
+        final Matcher matcher = DOCUMENT_PATTERN.matcher(documentId);
 
-        Preconditions.checkArgument( matcher.matches(), "Pattern for document 
id did not match expected format" );
-        Preconditions.checkArgument( matcher.groupCount() == 9, "9 groups 
expected in the pattern" );
+        Preconditions.checkArgument(matcher.matches(), "Pattern for document 
id did not match expected format");
+        Preconditions.checkArgument(matcher.groupCount() == 9, "9 groups 
expected in the pattern");
 
         //Other fields can be parsed using groups.  The groups start at value 
1, group 0 is the entire match
-        final String entityUUID = matcher.group( 3 );
-        final String entityType = matcher.group( 4 );
+        final String entityUUID = matcher.group(3);
+        final String entityType = matcher.group(4);
 
-        final String versionUUID = matcher.group( 5 );
+        final String versionUUID = matcher.group(5);
 
 
-        Id entityId = new SimpleId( UUID.fromString( entityUUID ), entityType 
);
+        Id entityId = new SimpleId(UUID.fromString(entityUUID), entityType);
 
-        return new CandidateResult( entityId, UUID.fromString( versionUUID ), 
documentId );
+        return distance>0
+            ? new GeoCandidateResult(entityId, UUID.fromString(versionUUID), 
documentId, distance)
+            : new CandidateResult(entityId, UUID.fromString(versionUUID), 
documentId);
     }
 
 

Reply via email to