Hazelcast 非重复键聚合
Hazelcast Distinct Key Aggregation
有没有办法使用 Hazelcast aggregation 来获得不同的 IMap
关键属性?
Aggregations.distinctValues()
along with a property extractor 允许获得不同的 value 属性;但是,我不确定如何使用聚合获得不同的 key 属性。
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;
}
}
}
您可以轻松实现自己的 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());
有没有办法使用 Hazelcast aggregation 来获得不同的 IMap
关键属性?
Aggregations.distinctValues()
along with a property extractor 允许获得不同的 value 属性;但是,我不确定如何使用聚合获得不同的 key 属性。
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;
}
}
}
您可以轻松实现自己的 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());