21
21
import java .util .List ;
22
22
import java .util .Map ;
23
23
24
+ import org .springframework .data .mongodb .core .aggregation .AggregationExpressions .Filter .AsBuilder ;
24
25
import org .springframework .data .mongodb .core .aggregation .ExposedFields .ExposedField ;
25
26
import org .springframework .data .mongodb .core .aggregation .ExposedFields .FieldReference ;
26
27
import org .springframework .util .Assert ;
@@ -662,7 +663,7 @@ private Substr createSubstr() {
662
663
*
663
664
* @return
664
665
*/
665
- private ToLower toLower () {
666
+ public ToLower toLower () {
666
667
return fieldRef != null ? ToLower .lowerValueOf (fieldRef ) : ToLower .lowerValueOf (expression );
667
668
}
668
669
@@ -671,7 +672,7 @@ private ToLower toLower() {
671
672
*
672
673
* @return
673
674
*/
674
- private ToUpper toUpper () {
675
+ public ToUpper toUpper () {
675
676
return fieldRef != null ? ToUpper .upperValueOf (fieldRef ) : ToUpper .upperValueOf (expression );
676
677
}
677
678
@@ -682,7 +683,7 @@ private ToUpper toUpper() {
682
683
* @param value must not be {@literal null}.
683
684
* @return
684
685
*/
685
- private StrCaseCmp strCaseCmp (String value ) {
686
+ public StrCaseCmp strCaseCmp (String value ) {
686
687
687
688
Assert .notNull (value , "Value must not be null!" );
688
689
return createStrCaseCmp ().strcasecmp (value );
@@ -695,7 +696,7 @@ private StrCaseCmp strCaseCmp(String value) {
695
696
* @param fieldRef must not be {@literal null}.
696
697
* @return
697
698
*/
698
- private StrCaseCmp strCaseCmpValueOf (String fieldRef ) {
699
+ public StrCaseCmp strCaseCmpValueOf (String fieldRef ) {
699
700
700
701
Assert .notNull (fieldRef , "FieldRef must not be null!" );
701
702
return createStrCaseCmp ().strcasecmpValueOf (fieldRef );
@@ -708,7 +709,7 @@ private StrCaseCmp strCaseCmpValueOf(String fieldRef) {
708
709
* @param expression must not be {@literal null}.
709
710
* @return
710
711
*/
711
- private StrCaseCmp strCaseCmpValueOf (AggregationExpression expression ) {
712
+ public StrCaseCmp strCaseCmpValueOf (AggregationExpression expression ) {
712
713
713
714
Assert .notNull (expression , "Expression must not be null!" );
714
715
return createStrCaseCmp ().strcasecmpValueOf (expression );
@@ -720,6 +721,155 @@ private StrCaseCmp createStrCaseCmp() {
720
721
}
721
722
}
722
723
724
+ /**
725
+ * @author Christoph Strobl
726
+ */
727
+ class ArrayOperators {
728
+
729
+ /**
730
+ * Take the array referenced by given {@literal fieldRef}.
731
+ *
732
+ * @param fieldRef must not be {@literal null}.
733
+ * @return
734
+ */
735
+ public static ArrayOperatorFactory arrayOf (String fieldRef ) {
736
+ return new ArrayOperatorFactory (fieldRef );
737
+ }
738
+
739
+ /**
740
+ * Take the array referenced by given {@literal fieldRef}.
741
+ *
742
+ * @param fieldRef must not be {@literal null}.
743
+ * @return
744
+ */
745
+ public static ArrayOperatorFactory arrayOf (AggregationExpression expression ) {
746
+ return new ArrayOperatorFactory (expression );
747
+ }
748
+
749
+ public static class ArrayOperatorFactory {
750
+
751
+ private final String fieldRef ;
752
+ private final AggregationExpression expression ;
753
+
754
+ public ArrayOperatorFactory (String fieldRef ) {
755
+ this .fieldRef = fieldRef ;
756
+ this .expression = null ;
757
+ }
758
+
759
+ public ArrayOperatorFactory (AggregationExpression expression ) {
760
+ this .fieldRef = null ;
761
+ this .expression = expression ;
762
+ }
763
+
764
+ /**
765
+ * Takes the associated array and returns the element at the specified array {@literal position}.
766
+ *
767
+ * @param position
768
+ * @return
769
+ */
770
+ public ArrayElemtAt elementAt (int position ) {
771
+ return createArrayElemAt ().elementAt (position );
772
+ }
773
+
774
+ /**
775
+ * Takes the associated array and returns the element at the position resulting form the given
776
+ * {@literal expression}.
777
+ *
778
+ * @param expression must not be {@literal null}.
779
+ * @return
780
+ */
781
+ public ArrayElemtAt elementAt (AggregationExpression expression ) {
782
+
783
+ Assert .notNull (expression , "Expression must not be null!" );
784
+ return createArrayElemAt ().elementAt (expression );
785
+ }
786
+
787
+ /**
788
+ * Takes the associated array and returns the element at the position defined by the referenced {@literal field}.
789
+ *
790
+ * @param fieldRef must not be {@literal null}.
791
+ * @return
792
+ */
793
+ public ArrayElemtAt elementAt (String fieldRef ) {
794
+
795
+ Assert .notNull (fieldRef , "FieldRef must not be null!" );
796
+ return createArrayElemAt ().elementAt (fieldRef );
797
+ }
798
+
799
+ private ArrayElemtAt createArrayElemAt () {
800
+ return usesFieldRef () ? ArrayElemtAt .arrayOf (fieldRef ) : ArrayElemtAt .arrayOf (expression );
801
+ }
802
+
803
+ /**
804
+ * Takes the associated array and concats the given {@literal arrayFieldReference} to it.
805
+ *
806
+ * @param arrayFieldReference must not be {@literal null}.
807
+ * @return
808
+ */
809
+ public ConcatArrays concat (String arrayFieldReference ) {
810
+
811
+ Assert .notNull (arrayFieldReference , "ArrayFieldReference must not be null!" );
812
+ return createConcatArrays ().concat (arrayFieldReference );
813
+ }
814
+
815
+ /**
816
+ * Takes the associated array and concats the array resulting form the given {@literal expression} to it.
817
+ *
818
+ * @param expression must not be {@literal null}.
819
+ * @return
820
+ */
821
+ public ConcatArrays concat (AggregationExpression expression ) {
822
+
823
+ Assert .notNull (expression , "Expression must not be null!" );
824
+ return createConcatArrays ().concat (expression );
825
+ }
826
+
827
+ private ConcatArrays createConcatArrays () {
828
+ return usesFieldRef () ? ConcatArrays .arrayOf (fieldRef ) : ConcatArrays .arrayOf (expression );
829
+ }
830
+
831
+ /**
832
+ * Takes the associated array and selects a subset of the array to return based on the specified condition.
833
+ *
834
+ * @return
835
+ */
836
+ public AsBuilder filter () {
837
+ return Filter .filter (fieldRef );
838
+ }
839
+
840
+ /**
841
+ * Takes the associated array and an check if its an array.
842
+ *
843
+ * @return
844
+ */
845
+ public IsArray isArray () {
846
+ return usesFieldRef () ? IsArray .isArray (fieldRef ) : IsArray .isArray (expression );
847
+ }
848
+
849
+ /**
850
+ * Takes the associated array and retrieves its length.
851
+ *
852
+ * @return
853
+ */
854
+ public Size length () {
855
+ return usesFieldRef () ? Size .lengthOfArray (fieldRef ) : Size .lengthOfArray (expression );
856
+ }
857
+
858
+ /**
859
+ * Takes the associated array and selects a subset from it.
860
+ *
861
+ * @return
862
+ */
863
+ public Slice slice () {
864
+ return usesFieldRef () ? Slice .sliceArrayOf (fieldRef ) : Slice .sliceArrayOf (expression );
865
+ }
866
+
867
+ private boolean usesFieldRef () {
868
+ return fieldRef != null ;
869
+ }
870
+ }
871
+ }
872
+
723
873
/**
724
874
* @author Christoph Strobl
725
875
*/
@@ -1679,7 +1829,76 @@ public StrCaseCmp strcasecmpValueOf(String fieldRef) {
1679
1829
public StrCaseCmp strcasecmpValueOf (AggregationExpression expression ) {
1680
1830
return new StrCaseCmp (append (expression ));
1681
1831
}
1832
+ }
1682
1833
1834
+ /**
1835
+ * {@link AggregationExpression} for {@code $arrayElementAt}.
1836
+ *
1837
+ * @author Christoph Strobl
1838
+ */
1839
+ class ArrayElemtAt extends AbstractAggregationExpression {
1840
+
1841
+ private ArrayElemtAt (List <?> value ) {
1842
+ super (value );
1843
+ }
1844
+
1845
+ @ Override
1846
+ public String getMongoMethod () {
1847
+ return "$arrayElemAt" ;
1848
+ }
1849
+
1850
+ public static ArrayElemtAt arrayOf (String fieldRef ) {
1851
+ return new ArrayElemtAt (asFields (fieldRef ));
1852
+ }
1853
+
1854
+ public static ArrayElemtAt arrayOf (AggregationExpression expression ) {
1855
+ return new ArrayElemtAt (Collections .singletonList (expression ));
1856
+ }
1857
+
1858
+ public ArrayElemtAt elementAt (int index ) {
1859
+ return new ArrayElemtAt (append (index ));
1860
+ }
1861
+
1862
+ public ArrayElemtAt elementAt (AggregationExpression expression ) {
1863
+ return new ArrayElemtAt (append (expression ));
1864
+ }
1865
+
1866
+ public ArrayElemtAt elementAt (String numericFieldRef ) {
1867
+ return new ArrayElemtAt (append (Fields .field (numericFieldRef )));
1868
+ }
1869
+ }
1870
+
1871
+ /**
1872
+ * {@link AggregationExpression} for {@code $concatArrays}.
1873
+ *
1874
+ * @author Christoph Strobl
1875
+ */
1876
+ class ConcatArrays extends AbstractAggregationExpression {
1877
+
1878
+ private ConcatArrays (List <?> value ) {
1879
+ super (value );
1880
+ }
1881
+
1882
+ @ Override
1883
+ public String getMongoMethod () {
1884
+ return "$concatArrays" ;
1885
+ }
1886
+
1887
+ public static ConcatArrays arrayOf (String fieldRef ) {
1888
+ return new ConcatArrays (asFields (fieldRef ));
1889
+ }
1890
+
1891
+ public static ConcatArrays arrayOf (AggregationExpression expression ) {
1892
+ return new ConcatArrays (Collections .singletonList (expression ));
1893
+ }
1894
+
1895
+ public ConcatArrays concat (String arrayFieldReference ) {
1896
+ return new ConcatArrays (append (Fields .field (arrayFieldReference )));
1897
+ }
1898
+
1899
+ public ConcatArrays concat (AggregationExpression expression ) {
1900
+ return new ConcatArrays (append (expression ));
1901
+ }
1683
1902
}
1684
1903
1685
1904
/**
@@ -1939,4 +2158,99 @@ public Filter by(DBObject expression) {
1939
2158
}
1940
2159
}
1941
2160
}
2161
+
2162
+ /**
2163
+ * {@link AggregationExpression} for {@code $isArray}.
2164
+ *
2165
+ * @author Christoph Strobl
2166
+ */
2167
+ class IsArray extends AbstractAggregationExpression {
2168
+
2169
+ private IsArray (Object value ) {
2170
+ super (value );
2171
+ }
2172
+
2173
+ @ Override
2174
+ public String getMongoMethod () {
2175
+ return "$isArray" ;
2176
+ }
2177
+
2178
+ public static IsArray isArray (String fieldRef ) {
2179
+ return new IsArray (Fields .field (fieldRef ));
2180
+ }
2181
+
2182
+ public static IsArray isArray (AggregationExpression expression ) {
2183
+ return new IsArray (expression );
2184
+ }
2185
+ }
2186
+
2187
+ /**
2188
+ * {@link AggregationExpression} for {@code $size}.
2189
+ *
2190
+ * @author Christoph Strobl
2191
+ */
2192
+ class Size extends AbstractAggregationExpression {
2193
+
2194
+ private Size (Object value ) {
2195
+ super (value );
2196
+ }
2197
+
2198
+ @ Override
2199
+ public String getMongoMethod () {
2200
+ return "$size" ;
2201
+ }
2202
+
2203
+ public static Size lengthOfArray (String fieldRef ) {
2204
+ return new Size (Fields .field (fieldRef ));
2205
+ }
2206
+
2207
+ public static Size lengthOfArray (AggregationExpression expression ) {
2208
+ return new Size (expression );
2209
+ }
2210
+ }
2211
+
2212
+ /**
2213
+ * {@link AggregationExpression} for {@code $slice}.
2214
+ *
2215
+ * @author Christoph Strobl
2216
+ */
2217
+ class Slice extends AbstractAggregationExpression {
2218
+
2219
+ private Slice (List <?> value ) {
2220
+ super (value );
2221
+ }
2222
+
2223
+ @ Override
2224
+ public String getMongoMethod () {
2225
+ return "$slice" ;
2226
+ }
2227
+
2228
+ public static Slice sliceArrayOf (String fieldRef ) {
2229
+ return new Slice (asFields (fieldRef ));
2230
+ }
2231
+
2232
+ public static Slice sliceArrayOf (AggregationExpression expression ) {
2233
+ return new Slice (Collections .singletonList (expression ));
2234
+ }
2235
+
2236
+ public Slice itemCount (int nrElements ) {
2237
+ return new Slice (append (nrElements ));
2238
+ }
2239
+
2240
+ public SliceElementsBuilder offset (final int position ) {
2241
+
2242
+ return new SliceElementsBuilder () {
2243
+
2244
+ @ Override
2245
+ public Slice itemCount (int nrElements ) {
2246
+ return new Slice (append (position )).itemCount (nrElements );
2247
+ }
2248
+ };
2249
+ }
2250
+
2251
+ public interface SliceElementsBuilder {
2252
+ Slice itemCount (int nrElements );
2253
+ }
2254
+ }
2255
+
1942
2256
}
0 commit comments