Skip to content

Commit a224353

Browse files
divyajnu08christophstrobl
authored andcommitted
Add support for $first & $last aggregation operators.
Closes: #3694 Original Pull Request: #3866
1 parent a36e292 commit a224353

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-0
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java

+133
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,36 @@ public ArrayToObject toObject() {
362362

363363
return usesExpression() ? ArrayToObject.arrayValueOfToObject(expression) : ArrayToObject.arrayToObject(values);
364364
}
365+
366+
/**
367+
* Creates new {@link AggregationExpression} that return the first element in the given array.
368+
* <strong>NOTE:</strong> Requires MongoDB 4.4 or later.
369+
*
370+
* @return new instance of {@link First}.
371+
*/
372+
public First first() {
373+
374+
if (usesFieldRef()) {
375+
return First.firstOf(fieldReference);
376+
}
377+
378+
return usesExpression() ? First.firstOf(expression) : First.first(values);
379+
}
380+
381+
/**
382+
* Creates new {@link AggregationExpression} that return the last element in the given array.
383+
* <strong>NOTE:</strong> Requires MongoDB 4.4 or later.
384+
*
385+
* @return new instance of {@link First}.
386+
*/
387+
public Last last() {
388+
389+
if (usesFieldRef()) {
390+
return Last.lastOf(fieldReference);
391+
}
392+
393+
return usesExpression() ? Last.lastOf(expression) : Last.last(values);
394+
}
365395

366396
/**
367397
* @author Christoph Strobl
@@ -1812,4 +1842,107 @@ protected String getMongoMethod() {
18121842
return "$arrayToObject";
18131843
}
18141844
}
1845+
1846+
/**
1847+
* {@link AggregationExpression} for {@code $first} that returns the first element in an array. <br />
1848+
* <strong>NOTE:</strong> Requires MongoDB 4.4 or later.
1849+
*
1850+
*/
1851+
public static class First extends AbstractAggregationExpression {
1852+
1853+
private First(Object value) {
1854+
super(value);
1855+
}
1856+
1857+
/**
1858+
* Returns the first element in the given array.
1859+
*
1860+
* @param array must not be {@literal null}.
1861+
* @return new instance of {@link First}.
1862+
*/
1863+
public static First first(Object array) {
1864+
return new First(array);
1865+
}
1866+
1867+
/**
1868+
* Returns the first element in the array pointed to by the given {@link Field field reference}.
1869+
*
1870+
* @param fieldReference must not be {@literal null}.
1871+
* @return new instance of {@link First}.
1872+
*/
1873+
public static First firstOf(String fieldReference) {
1874+
return new First(Fields.field(fieldReference));
1875+
}
1876+
1877+
/**
1878+
* Returns the first element of the array of the given {@link AggregationExpression expression}.
1879+
*
1880+
* @param expression must not be {@literal null}.
1881+
* @return new instance of {@link First}.
1882+
*/
1883+
public static First firstOf(AggregationExpression expression) {
1884+
return new First(expression);
1885+
}
1886+
1887+
/*
1888+
* (non-Javadoc)
1889+
* @see org.springframework.data.mongodb.core.aggregation.AbstractAggregationExpression#getMongoMethod()
1890+
*/
1891+
@Override
1892+
protected String getMongoMethod() {
1893+
return "$first";
1894+
}
1895+
}
1896+
1897+
/**
1898+
* {@link AggregationExpression} for {@code $last} that returns the last element in an array. <br />
1899+
* <strong>NOTE:</strong> Requires MongoDB 4.4 or later.
1900+
*
1901+
*/
1902+
public static class Last extends AbstractAggregationExpression {
1903+
1904+
private Last(Object value) {
1905+
super(value);
1906+
}
1907+
1908+
/**
1909+
* Returns the first element in the given array.
1910+
*
1911+
* @param array must not be {@literal null}.
1912+
* @return new instance of {@link Last}.
1913+
*/
1914+
public static Last last(Object array) {
1915+
return new Last(array);
1916+
}
1917+
1918+
/**
1919+
* Returns the last element in the array pointed to by the given {@link Field field reference}.
1920+
*
1921+
* @param fieldReference must not be {@literal null}.
1922+
* @return new instance of {@link Last}.
1923+
*/
1924+
public static Last lastOf(String fieldReference) {
1925+
return new Last(Fields.field(fieldReference));
1926+
}
1927+
1928+
/**
1929+
* Returns the last element of the array of the given {@link AggregationExpression expression}.
1930+
*
1931+
* @param expression must not be {@literal null}.
1932+
* @return new instance of {@link Last}.
1933+
*/
1934+
public static Last lastOf(AggregationExpression expression) {
1935+
return new Last(expression);
1936+
}
1937+
1938+
/*
1939+
* (non-Javadoc)
1940+
* @see org.springframework.data.mongodb.core.aggregation.AbstractAggregationExpression#getMongoMethod()
1941+
*/
1942+
@Override
1943+
protected String getMongoMethod() {
1944+
return "$last";
1945+
}
1946+
}
1947+
18151948
}

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ArrayOperatorsUnitTests.java

+43
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,47 @@ public void inWithValueList() {
129129
assertThat(ArrayOperators.arrayOf(VALUE_LIST).containsValue("$userName").toDocument(Aggregation.DEFAULT_CONTEXT))
130130
.isEqualTo("{ \"$in\" : [\"$userName\", " + VALUE_LIST_STRING + "] }");
131131
}
132+
133+
@Test
134+
public void firstWithValueList() {
135+
136+
assertThat(ArrayOperators.arrayOf(VALUE_LIST).first().toDocument(Aggregation.DEFAULT_CONTEXT))
137+
.isEqualTo("{ \"$first\" : " + VALUE_LIST_STRING + "}");
138+
}
139+
140+
@Test
141+
public void firstWithExpression() {
142+
143+
assertThat(ArrayOperators.arrayOf(EXPRESSION).first().toDocument(Aggregation.DEFAULT_CONTEXT))
144+
.isEqualTo("{ \"$first\" : " + EXPRESSION_STRING + "}");
145+
}
146+
147+
@Test
148+
public void firstWithFieldReference() {
149+
150+
assertThat(ArrayOperators.arrayOf("field").first().toDocument(Aggregation.DEFAULT_CONTEXT))
151+
.isEqualTo("{ $first : \"$field\" }");
152+
}
153+
154+
@Test
155+
public void lastWithValueList() {
156+
157+
assertThat(ArrayOperators.arrayOf(VALUE_LIST).last().toDocument(Aggregation.DEFAULT_CONTEXT))
158+
.isEqualTo("{ \"$last\" : " + VALUE_LIST_STRING + "}");
159+
}
160+
161+
@Test
162+
public void lastWithExpression() {
163+
164+
assertThat(ArrayOperators.arrayOf(EXPRESSION).last().toDocument(Aggregation.DEFAULT_CONTEXT))
165+
.isEqualTo("{ \"$last\" : " + EXPRESSION_STRING + "}");
166+
}
167+
168+
@Test
169+
public void lastWithFieldReference() {
170+
171+
assertThat(ArrayOperators.arrayOf("field").last().toDocument(Aggregation.DEFAULT_CONTEXT))
172+
.isEqualTo("{ $last : \"$field\" }");
173+
}
174+
132175
}

0 commit comments

Comments
 (0)