在有两个事实的groupBy中获取count()



如何在一个有两个事实的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,但我需要一个intLong

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的剩余部分

这样,您就可以从约束中获得最大的性能。

最新更新