如何在一个有两个事实的groupBy中获得计数的结果。
上下文:
private Constraint exampleConstraint(ConstraintFactory constraintFactory) {
return constraintFactory
.from(Journey.class)
.filter((Journey1) -> journey1.isValid())
.join(Journey.class, Joiners.filtering((Journey1, Journey2) -> (
Journey2.getDayJava().equals(Journey1.getDayJava()) && Journey2.isValid()
)))
.groupBy((Journey1, Journey2) -> Journey2,
(Journey1,Journey2) -> ConstraintCollectors.count())
.penalizeConfigurable(MY_CONSTRAINT, (Journey2, resultOfCount) -> Journey2.getDelta() - resultOfCount);
}
我的问题示例:
.groupBy((journey1, journey2) -> journey2,
(journey1,journey2) -> ConstraintCollectors.count())
第二组返回一个org.optaplanner.core.api.score.stream.uni.UninconstraintCollector,但我需要一个int或Long。
Thanx
您的代码片段显示了对该概念的误解。
首先,约束收集器不是用作组键,而是用作独立的参数。其次,ConstraintCollectors.count()
将无法与BiConstraintStream
一起工作。为此,您必须使用ConstraintCollectors.countBi()
。
综合来看,更正后的代码片段如下所示:
private Constraint exampleConstraint(ConstraintFactory constraintFactory) {
return constraintFactory
.from(Journey.class)
.filter((Journey1) -> journey1.isValid())
.join(Journey.class,
Joiners.filtering((Journey1, Journey2) ->
Journey2.getDayJava().equals(Journey1.getDayJava()) && Journey2.isValid()))
.groupBy((Journey1, Journey2) -> Journey2,
ConstraintCollectors.countBi())
.penalizeConfigurable(MY_CONSTRAINT, (Journey2, resultOfCount) -> Journey2.getDelta() - resultOfCount);
}
然而,在这方面也有相当大的性能改进潜力。filtering()
joiner没有索引,有一种方法可以用完全索引的操作来替换它,如下所示:
private Constraint exampleConstraint(ConstraintFactory constraintFactory) {
return constraintFactory.from(Journey.class)
.filter(Journey::isValid)
.join(
constrainFactory.forEach(Journey.class)
.filter(Journey::isValid),
Joiners.equal(Journey::getDayJava))
.groupBy((Journey1, Journey2) -> Journey2,
ConstraintCollectors.countBi())
.penalizeConfigurable(MY_CONSTRAINT, (Journey2, resultOfCount) -> Journey2.getDelta() - resultOfCount);
}
正如你所看到的,我做了两件事:
- 我预先过滤了进入加入的流
- 我用完全索引的
equals()
joiner替换了filtering()
joiner的剩余部分
这样,您就可以从约束中获得最大的性能。