|
17 | 17 | package com.mongodb.client.model;
|
18 | 18 |
|
19 | 19 | import com.mongodb.MongoNamespace;
|
| 20 | +import com.mongodb.annotations.Beta; |
20 | 21 | import com.mongodb.lang.Nullable;
|
21 | 22 | import org.bson.BsonBoolean;
|
22 | 23 | import org.bson.BsonDocument;
|
|
28 | 29 | import org.bson.conversions.Bson;
|
29 | 30 |
|
30 | 31 | import java.util.List;
|
| 32 | +import java.util.Objects; |
31 | 33 |
|
32 | 34 | import static java.util.Arrays.asList;
|
33 | 35 | import static org.bson.assertions.Assertions.notNull;
|
@@ -594,6 +596,60 @@ public static Bson sample(final int size) {
|
594 | 596 | return new BsonDocument("$sample", new BsonDocument("size", new BsonInt32(size)));
|
595 | 597 | }
|
596 | 598 |
|
| 599 | + /** |
| 600 | + * Creates a {@code $setWindowFields} pipeline stage, which allows using window operators. |
| 601 | + * This stage partitions the input documents similarly to the {@link #group(Object, List) $group} pipeline stage, |
| 602 | + * optionally sorts them, computes fields in the documents by computing window functions over {@linkplain Window windows} specified per |
| 603 | + * function, and outputs the documents. The important difference from the {@code $group} pipeline stage is that |
| 604 | + * documents belonging to the same partition or window are not folded into a single document. |
| 605 | + * |
| 606 | + * @param partitionBy Optional partitioning of data specified like {@code id} in {@link #group(Object, List)}. |
| 607 | + * If {@code null}, then all documents belong to the same partition. |
| 608 | + * @param sortBy Fields to sort by. The syntax is identical to {@code sort} in {@link #sort(Bson)} (see {@link Sorts}). |
| 609 | + * Sorting is required by certain functions and may be required by some windows (see {@link Windows} for more details). |
| 610 | + * Sorting is used only for the purpose of computing window functions and does not guarantee ordering |
| 611 | + * of the output documents. |
| 612 | + * @param output A nonempty array of {@linkplain WindowedComputation windowed computations}. |
| 613 | + * @param <TExpression> The {@code partitionBy} expression type. |
| 614 | + * @return The {@code $setWindowFields} pipeline stage. |
| 615 | + * @mongodb.driver.dochub core/window-functions-set-window-fields $setWindowFields |
| 616 | + * @mongodb.server.release 5.0 |
| 617 | + * @since 4.3 |
| 618 | + */ |
| 619 | + @Beta |
| 620 | + public static <TExpression> Bson setWindowFields(@Nullable final TExpression partitionBy, @Nullable final Bson sortBy, |
| 621 | + final WindowedComputation... output) { |
| 622 | + notNull("output", output); |
| 623 | + return setWindowFields(partitionBy, sortBy, asList(output)); |
| 624 | + } |
| 625 | + |
| 626 | + /** |
| 627 | + * Creates a {@code $setWindowFields} pipeline stage, which allows using window operators. |
| 628 | + * This stage partitions the input documents similarly to the {@link #group(Object, List) $group} pipeline stage, |
| 629 | + * optionally sorts them, computes fields in the documents by computing window functions over {@linkplain Window windows} specified per |
| 630 | + * function, and outputs the documents. The important difference from the {@code $group} pipeline stage is that |
| 631 | + * documents belonging to the same partition or window are not folded into a single document. |
| 632 | + * |
| 633 | + * @param partitionBy Optional partitioning of data specified like {@code id} in {@link #group(Object, List)}. |
| 634 | + * If {@code null}, then all documents belong to the same partition. |
| 635 | + * @param sortBy Fields to sort by. The syntax is identical to {@code sort} in {@link #sort(Bson)} (see {@link Sorts}). |
| 636 | + * Sorting is required by certain functions and may be required by some windows (see {@link Windows} for more details). |
| 637 | + * Sorting is used only for the purpose of computing window functions and does not guarantee ordering |
| 638 | + * of the output documents. |
| 639 | + * @param output A nonempty list of {@linkplain WindowedComputation windowed computations}. |
| 640 | + * @param <TExpression> The {@code partitionBy} expression type. |
| 641 | + * @return The {@code $setWindowFields} pipeline stage. |
| 642 | + * @mongodb.driver.dochub core/window-functions-set-window-fields $setWindowFields |
| 643 | + * @mongodb.server.release 5.0 |
| 644 | + * @since 4.3 |
| 645 | + */ |
| 646 | + @Beta |
| 647 | + public static <TExpression> Bson setWindowFields(@Nullable final TExpression partitionBy, @Nullable final Bson sortBy, |
| 648 | + final List<WindowedComputation> output) { |
| 649 | + notNull("output", output); |
| 650 | + return new SetWindowFieldsStage<>(partitionBy, sortBy, output); |
| 651 | + } |
| 652 | + |
597 | 653 | static void writeBucketOutput(final CodecRegistry codecRegistry, final BsonDocumentWriter writer,
|
598 | 654 | @Nullable final List<BsonField> output) {
|
599 | 655 | if (output != null) {
|
@@ -1490,6 +1546,72 @@ public String toString() {
|
1490 | 1546 | }
|
1491 | 1547 | }
|
1492 | 1548 |
|
| 1549 | + private static final class SetWindowFieldsStage<TExpression> implements Bson { |
| 1550 | + @Nullable |
| 1551 | + private final TExpression partitionBy; |
| 1552 | + @Nullable |
| 1553 | + private final Bson sortBy; |
| 1554 | + private final List<WindowedComputation> output; |
| 1555 | + |
| 1556 | + SetWindowFieldsStage(@Nullable final TExpression partitionBy, @Nullable final Bson sortBy, final List<WindowedComputation> output) { |
| 1557 | + this.partitionBy = partitionBy; |
| 1558 | + this.sortBy = sortBy; |
| 1559 | + this.output = output; |
| 1560 | + } |
| 1561 | + |
| 1562 | + @Override |
| 1563 | + public <TDocument> BsonDocument toBsonDocument(final Class<TDocument> tDocumentClass, final CodecRegistry codecRegistry) { |
| 1564 | + BsonDocumentWriter writer = new BsonDocumentWriter(new BsonDocument()); |
| 1565 | + writer.writeStartDocument(); |
| 1566 | + writer.writeStartDocument("$setWindowFields"); |
| 1567 | + if (partitionBy != null) { |
| 1568 | + writer.writeName("partitionBy"); |
| 1569 | + BuildersHelper.encodeValue(writer, partitionBy, codecRegistry); |
| 1570 | + } |
| 1571 | + if (sortBy != null) { |
| 1572 | + writer.writeName("sortBy"); |
| 1573 | + BuildersHelper.encodeValue(writer, sortBy, codecRegistry); |
| 1574 | + } |
| 1575 | + writer.writeStartDocument("output"); |
| 1576 | + for (WindowedComputation windowedComputation : output) { |
| 1577 | + BsonField field = windowedComputation.toBsonField(); |
| 1578 | + writer.writeName(field.getName()); |
| 1579 | + BuildersHelper.encodeValue(writer, field.getValue(), codecRegistry); |
| 1580 | + } |
| 1581 | + writer.writeEndDocument(); // end output |
| 1582 | + writer.writeEndDocument(); // end $setWindowFields |
| 1583 | + writer.writeEndDocument(); |
| 1584 | + return writer.getDocument(); |
| 1585 | + } |
| 1586 | + |
| 1587 | + @Override |
| 1588 | + public boolean equals(final Object o) { |
| 1589 | + if (this == o) { |
| 1590 | + return true; |
| 1591 | + } |
| 1592 | + if (o == null || getClass() != o.getClass()) { |
| 1593 | + return false; |
| 1594 | + } |
| 1595 | + final SetWindowFieldsStage<?> that = (SetWindowFieldsStage<?>) o; |
| 1596 | + return Objects.equals(partitionBy, that.partitionBy) && Objects.equals(sortBy, that.sortBy) && output.equals(that.output); |
| 1597 | + } |
| 1598 | + |
| 1599 | + @Override |
| 1600 | + public int hashCode() { |
| 1601 | + return Objects.hash(partitionBy, sortBy, output); |
| 1602 | + } |
| 1603 | + |
| 1604 | + @Override |
| 1605 | + public String toString() { |
| 1606 | + return "Stage{" |
| 1607 | + + "name='$setWindowFields'" |
| 1608 | + + ", partitionBy=" + partitionBy |
| 1609 | + + ", sortBy=" + sortBy |
| 1610 | + + ", output=" + output |
| 1611 | + + '}'; |
| 1612 | + } |
| 1613 | + } |
| 1614 | + |
1493 | 1615 | private Aggregates() {
|
1494 | 1616 | }
|
1495 | 1617 | }
|
0 commit comments