2016-03-04 81 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