GroupingExpression extends EvaluationExpression { @Override public IJsonNode evaluate(final IJsonNode node, final IJsonNode target, final EvaluationContext context) { final ArrayNode targetArray = SopremoUtil.reinitializeTarget(target, ArrayNode.class); if (((IArrayNode) node).size() == 0) return targetArray; final List<IArrayNode> nodes = this.sortNodesWithKey(node, context); int groupStart = 0; IJsonNode groupKey = nodes.get(0).get(0); for (int index = 1; index < nodes.size(); index++) if (!nodes.get(index).get(0).equals(groupKey)) { targetArray.add(this.evaluateGroup(nodes.subList(groupStart, index), context)); groupKey = nodes.get(index).get(0); groupStart = index; } targetArray.add(this.evaluateGroup(nodes.subList(groupStart, nodes.size()), context)); return targetArray; } GroupingExpression(final EvaluationExpression groupingExpression, final EvaluationExpression resultExpression); @Override IJsonNode evaluate(final IJsonNode node, final IJsonNode target, final EvaluationContext context); @Override EvaluationExpression transformRecursively(final TransformFunction function); @Override int hashCode(); @Override boolean equals(final Object obj); @Override void toString(final StringBuilder builder);  }
@Test public void testAggregation() { this.context.getFunctionRegistry().put(CoreFunctions.class); final ArrayNode input = new ArrayNode(); input.add(createObjectNode("key", 1, "value", 11)); input.add(createObjectNode("key", 2, "value", 24)); input.add(createObjectNode("key", 3, "value", 33)); input.add(createObjectNode("key", 2, "value", 25)); input.add(createObjectNode("key", 1, "value", 12)); final GroupingExpression aggExpression = new GroupingExpression(new ObjectAccess("key"), new FunctionCall("sum", this.context, new ArrayProjection(new ObjectAccess("value")))); final IJsonNode result = aggExpression.evaluate(input, null, this.context); final ArrayNode expected = new ArrayNode(); expected.add(createValueNode(23)); expected.add(createValueNode(49)); expected.add(createValueNode(33)); Assert.assertEquals(expected, result); }
@Test public void shouldReuseTarget() { IJsonNode target = new ArrayNode(); this.context.getFunctionRegistry().put(CoreFunctions.class); final ArrayNode input = new ArrayNode(); input.add(createObjectNode("key", 1, "value", 11)); input.add(createObjectNode("key", 2, "value", 24)); input.add(createObjectNode("key", 3, "value", 33)); input.add(createObjectNode("key", 2, "value", 25)); input.add(createObjectNode("key", 1, "value", 12)); final GroupingExpression aggExpression = new GroupingExpression(new ObjectAccess("key"), new FunctionCall("sum", this.context, new ArrayProjection(new ObjectAccess("value")))); final IJsonNode result = aggExpression.evaluate(input, target, this.context); final ArrayNode expected = new ArrayNode(); expected.add(createValueNode(23)); expected.add(createValueNode(49)); expected.add(createValueNode(33)); Assert.assertEquals(expected, result); Assert.assertSame(target, result); }
@Test public void shouldNotReuseTargetIfWrongType() { IJsonNode target = new ObjectNode(); this.context.getFunctionRegistry().put(CoreFunctions.class); final ArrayNode input = new ArrayNode(); input.add(createObjectNode("key", 1, "value", 11)); input.add(createObjectNode("key", 2, "value", 24)); input.add(createObjectNode("key", 3, "value", 33)); input.add(createObjectNode("key", 2, "value", 25)); input.add(createObjectNode("key", 1, "value", 12)); final GroupingExpression aggExpression = new GroupingExpression(new ObjectAccess("key"), new FunctionCall("sum", this.context, new ArrayProjection(new ObjectAccess("value")))); final IJsonNode result = aggExpression.evaluate(input, target, this.context); final ArrayNode expected = new ArrayNode(); expected.add(createValueNode(23)); expected.add(createValueNode(49)); expected.add(createValueNode(33)); Assert.assertEquals(expected, result); Assert.assertNotSame(target, result); }