2016-03-04 54 views
1

有没有办法使用Hazelcast aggregation获得不同的IMap关键属性?Hazelcast独特的关键聚合

Aggregations.distinctValues()以及property extractor允许获得不同的属性;但是,我不知道如何使用聚合获得明显的属性。

public class AggregationTest { 

    public static void main(String[] args) throws Exception { 

     HazelcastInstance instance = Hazelcast.getOrCreateHazelcastInstance(new Config("hazelcast1")); 

     // Create map with test values 
     IMap<MapKey, MapValue> map = instance.getMap("tenantUserMap"); 
     map.set(new MapKey("tenantA", "userA"), new MapValue("someMapValue1")); 
     map.set(new MapKey("tenantA", "userB"), new MapValue("someMapValue2")); 
     map.set(new MapKey("tenantB", "userA"), new MapValue("someMapValue1")); 

     // Use case: Obtain counts for each tenant (a property of the map's key) 
     // FIXME In order to iterate over each tenant to obtain a count, how do we get the list of distinct key properties?? 
     Long tenantACount = map.aggregate(Supplier.fromKeyPredicate(new TenantKeyPredicate("tenantA")), Aggregations.count()); 
     Long tenantBCount = map.aggregate(Supplier.fromKeyPredicate(new TenantKeyPredicate("tenantB")), Aggregations.count()); 
     Long unknownTenantCount = map.aggregate(Supplier.fromKeyPredicate(new TenantKeyPredicate("unknown")), Aggregations.count()); 

     System.out.println("tenantA count: " + tenantACount); 
     System.out.println("tenantB count: " + tenantBCount); 
     System.out.println("unknown count: " + unknownTenantCount); 

     // It is easily possible to obtain distinct VALUE properties... but how to obtain distinct KEY properties? 
     Set<Object> distinctValues = map.aggregate(Supplier.all(value -> value.getValue()), Aggregations.distinctValues()); 
     System.out.println("distinct values: " + distinctValues); 

     instance.shutdown(); 
    } 

    static class TenantKeyPredicate implements KeyPredicate<MapKey> { 

     private static final long serialVersionUID = 5073272969705387966L; 

     private final String tenant; 

     public TenantKeyPredicate(String tenant) { 
      this.tenant = tenant; 
     } 

     @Override 
     public boolean evaluate(MapKey key) { 
      return tenant.equals(key.getTenant()); 
     } 
    } 

    static class MapKey implements Serializable { 

     private static final long serialVersionUID = -4067718572086979235L; 

     private final String tenant; 
     private final String username; 

     MapKey(String tenant, String username) { 
      this.tenant = tenant; 
      this.username = username; 
     } 

     public String getTenant() { 
      return tenant; 
     } 

     public String getUsername() { 
      return username; 
     } 

    } 

    static class MapValue implements Serializable { 

     private static final long serialVersionUID = 7173400494627910565L; 

     private final String value; 

     MapValue(String value) { 
      this.value = value; 
     } 

     public String getValue() { 
      return value; 
     } 

    } 

} 

回答

2

您可以轻松实现自己的Supplier

供应商只是一个知道如何从地图条目提取数据的组件。在你的情况下,你想从密钥中提取数据。因为在Hazelcast中这不是一个常见的情况(最好有一个简单的密钥),所以没有一个通用的实现。

然而,在你的情况下,这个实现很简单:

public class TenantSupplier extends Supplier<MapKey, MapValue, String> { 

    @Override 
    public String apply(Entry<MapKey, MapValue> entry) { 
     return entry.getKey().getTenant(); 
    } 
} 

然后,您可以聚集在按键的租户,这个供应商:

Set<String> uniqueTenant = map.aggregate(new TenantSupplier(), 
       Aggregations.<MapKey, String, String>distinctValues()); 
+0

我希望我失去了一些东西明显有是一个简单的答案,事实上确实如此。谢谢! – shelley