如何从 hazelcast 地图中获取随机键值

问题描述

我试图像这样从 Map 中获取一个随机元素

IMap<Integer,Integer> workWaitTasks = hazelcastInstance.getMap(WORK_WAIT_TASKS);
collectionTask = Collections.singleton(workWaitTasks.values().stream()
                .skip(workWaitTasks.isEmpty() ? 0 : new Random().nextInt(workWaitTasks.size()))
                .findFirst()
                .get());
int taskId = collectionTask.iterator().next();

但我认为最好的方法是使用谓词

我读过这个https://docs.hazelcast.com/imdg/4.2/query/how-distributed-query-works.html#querying-with-sql-like-predicates 不幸的是,这对我没有帮助

我找不到办法做到这一点

sql中是这样的

 SELECT column FROM table
 ORDER BY RAND()
 LIMIT 1

如何在hazelcast中做出正确的谓词?

能举个例子吗?请帮帮我

解决方法

我认为使用公共 API 没有简单有效的方法来做到这一点。一种选择是使用 Jet:

IMap<Object,Object> sourceMap = instance.getMap("table");
IList<Object> targetList = instance.getList("result");
int samplingFactor = sourceMap.size() / 10;
Pipeline p = Pipeline.create();
p.readFrom(Sources.map(sourceMap))
        .filter(item -> item.getKey().hashCode() % samplingFactor == ThreadLocalRandom.current().nextInt(samplingFactor))
        .writeTo(Sinks.list(targetList));

instance.newJob(p).join();

上面的代码应该将大约 10 个元素添加到结果列表中,从中很容易获得一个随机条目,但也可能最终得到一个空列表 - 您可以尝试增加 samplingFactor 中的乘数获得满意的结果,而不必重新运行作业。

使用带有自定义聚合器的聚合 (IMap.aggregate) 也可以实现同样的效果,某些同事可能会提供答案:-)。