You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by mr...@apache.org on 2016/06/03 14:45:54 UTC

[04/26] usergrid git commit: Initial support for select mappings with entity object fields (i.e. nested fields)

Initial support for select mappings with entity object fields (i.e. nested fields)


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

Branch: refs/heads/release-2.1.1
Commit: 596e0fc5cef2eb1ae4aba40343bf27e73aee86d6
Parents: 7fdca3d
Author: Dave Johnson <sn...@apache.org>
Authored: Wed May 18 17:24:25 2016 -0400
Committer: Dave Johnson <sn...@apache.org>
Committed: Wed May 18 17:24:25 2016 -0400

----------------------------------------------------------------------
 .../read/search/CandidateEntityFilter.java      | 59 ++++++++++++++-
 .../apache/usergrid/persistence/IndexIT.java    | 80 ++++++++++++++++++++
 2 files changed, 135 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/usergrid/blob/596e0fc5/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 d47e96c..261259b 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
@@ -27,7 +27,9 @@ 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.EntityObjectField;
 import org.apache.usergrid.persistence.model.field.Field;
+import org.apache.usergrid.persistence.model.field.value.EntityObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -123,12 +125,26 @@ public class CandidateEntityFilter extends AbstractFilter<FilterResult<Candidate
                                 if (mappings.size() > 0) {
                                     Map<String,Field> fieldMap = new HashMap<String, Field>(mappings.size());
                                     rx.Observable.from(mappings)
-                                        .filter(mapping -> entity.getFieldMap().containsKey(mapping.getSourceFieldName()))
+
+                                        .filter(mapping -> {
+                                            if ( entity.getFieldMap().containsKey(mapping.getSourceFieldName())) {
+                                                return true;
+                                            }
+                                            String[] parts = mapping.getSourceFieldName().split("\\.");
+                                            return nestedFieldCheck( parts, entity.getFieldMap() );
+                                        })
+
                                         .doOnNext(mapping -> {
                                             Field field = entity.getField(mapping.getSourceFieldName());
-                                            field.setName(mapping.getTargetFieldName());
-                                            fieldMap.put(mapping.getTargetFieldName(),field);
-                                        }).toBlocking().last();
+                                            if ( field != null ) {
+                                                field.setName( mapping.getTargetFieldName() );
+                                                fieldMap.put( mapping.getTargetFieldName(), field );
+                                            } else {
+                                                String[] parts = mapping.getSourceFieldName().split("\\.");
+                                                nestedFieldSet( fieldMap, parts, entity.getFieldMap() );
+                                            }
+                                        }).toBlocking().lastOrDefault(null);
+
                                     entity.setFieldMap(fieldMap);
                                 }
                                 return entityFilterResult;
@@ -144,6 +160,41 @@ public class CandidateEntityFilter extends AbstractFilter<FilterResult<Candidate
     }
 
 
+    private void nestedFieldSet( Map<String, Field> result, String[] parts, Map<String, Field> fieldMap) {
+        if ( parts.length > 0 ) {
+            if ( fieldMap.containsKey( parts[0] )) {
+                Field field = fieldMap.get( parts[0] );
+                if ( field instanceof EntityObjectField ) {
+                    EntityObjectField eof = (EntityObjectField)field;
+                    if ( result.get( parts[0] ) == null ) {
+                        result.put( parts[0], new EntityObjectField( parts[0], new EntityObject() ) );
+                    }
+                    nestedFieldSet(
+                        ((EntityObjectField)result.get( parts[0] )).getValue().getFieldMap(),
+                        Arrays.copyOfRange(parts, 1, parts.length),
+                        eof.getValue().getFieldMap());
+                } else {
+                    result.put( parts[0], field );
+                }
+            }
+        }
+    }
+
+
+    private boolean nestedFieldCheck( String[] parts, Map<String, Field> fieldMap) {
+        if ( parts.length > 0 ) {
+            if ( fieldMap.containsKey( parts[0] )) {
+                Field field = fieldMap.get( parts[0] );
+                if ( field instanceof EntityObjectField ) {
+                    EntityObjectField eof = (EntityObjectField)field;
+                    return nestedFieldCheck( Arrays.copyOfRange(parts, 1, parts.length), eof.getValue().getFieldMap());
+                } else {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
 
 
     /**

http://git-wip-us.apache.org/repos/asf/usergrid/blob/596e0fc5/stack/core/src/test/java/org/apache/usergrid/persistence/IndexIT.java
----------------------------------------------------------------------
diff --git a/stack/core/src/test/java/org/apache/usergrid/persistence/IndexIT.java b/stack/core/src/test/java/org/apache/usergrid/persistence/IndexIT.java
index f4aa204..7e38f17 100644
--- a/stack/core/src/test/java/org/apache/usergrid/persistence/IndexIT.java
+++ b/stack/core/src/test/java/org/apache/usergrid/persistence/IndexIT.java
@@ -17,6 +17,7 @@
 package org.apache.usergrid.persistence;
 
 
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.UUID;
@@ -461,4 +462,83 @@ public class IndexIT extends AbstractCoreIT {
 
 
     }
+
+    @Test
+    public void testSelectMappings() throws Exception {
+
+        UUID applicationId = app.getId();
+
+        EntityManager em = setup.getEmf().getEntityManager(applicationId);
+
+        Map<String, Object> entity1 = new HashMap<String, Object>() {{
+            put("name","name_1");
+            put("status", "pickled");
+            put("data", new HashMap() {{
+                put("xfactor", 5.1);
+                put("rando", "bar");
+            }});
+        }};
+        em.create("names", entity1);
+
+        Map<String, Object> entity2 = new HashMap<String, Object>() {{
+            put("name","name_2");
+            put("status", "pickled");
+            put("data", new HashMap() {{
+                put("xfactor", 5.1);
+                put("rando", "bar");
+            }});
+        }};
+        em.create("names", entity2);
+
+        app.refreshIndex();
+
+        {
+            Query query = Query.fromQL("select status where status = 'pickled'");
+            Results r = em.searchCollection( em.getApplicationRef(), "names", query );
+            assertTrue(r.getEntities() != null && r.getEntities().size() == 2);
+            Entity first =  r.getEntities().get(0);
+            assertTrue(first.getDynamicProperties().size() == 2);
+        }
+
+        {
+            Query query = Query.fromQL( "select status, data.rando where data.rando = 'bar'" );
+            Results r = em.searchCollection( em.getApplicationRef(), "names", query );
+            assertTrue( r.getEntities() != null && r.getEntities().size() == 2 );
+
+            Entity first = r.getEntities().get( 0 );
+
+            assertNotNull( first.getProperty("status") );
+            assertEquals( first.getProperty("status"), "pickled" );
+
+            assertNotNull( first.getProperty("data") );
+            assertEquals( ((Map<String, Object>)first.getProperty("data")).get("rando"), "bar" );
+
+            assertTrue( first.getDynamicProperties().size() == 3 );
+        }
+
+        {
+            //  query for only one bogus field name should return empty entities
+            Query query = Query.fromQL( "select data.rando where status = 'pickled'" );
+            Results r = em.searchCollection( em.getApplicationRef(), "names", query );
+            assertTrue( r.getEntities() != null && r.getEntities().size() == 2 );
+
+            Entity first = r.getEntities().get( 0 );
+
+            assertNotNull( first.getProperty("data") );
+            assertEquals( ((Map<String, Object>)first.getProperty("data")).get("rando"), "bar" );
+
+            assertTrue( first.getDynamicProperties().size() == 2 );
+        }
+
+        {
+            //  query for only one bogus field name should return empty entities
+            Query query = Query.fromQL( "select data.bogusfieldname where status = 'pickled'" );
+            Results r = em.searchCollection( em.getApplicationRef(), "names", query );
+            assertTrue( r.getEntities() != null && r.getEntities().size() == 2 );
+            Entity first = r.getEntities().get( 0 );
+            assertTrue( first.getDynamicProperties().size() == 1 );
+        }
+
+    }
+
 }