Skip to content
This repository was archived by the owner on May 8, 2026. It is now read-only.

Commit ffdcffb

Browse files
committed
feat: add support for remaining map pipeline expressions
Adds support for `mapSet`, `mapKeys`, `mapValues`, `mapEntries` pipeline expressions.
1 parent 0af6f0b commit ffdcffb

3 files changed

Lines changed: 451 additions & 0 deletions

File tree

google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Expression.java

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,17 @@ public static Expression constant(VectorValue value) {
178178
return new Constant(value);
179179
}
180180

181+
/**
182+
* Create a constant for an arbitrary value (e.g. Map, List).
183+
*
184+
* @param value The value.
185+
* @return A new {@link Expression} constant instance.
186+
*/
187+
@BetaApi
188+
public static Expression constant(Object value) {
189+
return new Constant(value);
190+
}
191+
181192
/**
182193
* Constant for a null value.
183194
*
@@ -1955,6 +1966,172 @@ public static Expression mapRemove(String mapField, String key) {
19551966
return mapRemove(field(mapField), key);
19561967
}
19571968

1969+
/**
1970+
* Creates an expression that returns a new map with the specified entries added or updated.
1971+
*
1972+
* <ul>
1973+
* <li>Only performs shallow updates to the map.</li>
1974+
* <li>Setting a value to {@code null} will retain the key with a {@code null} value. To remove a
1975+
* key entirely, use {@code mapRemove}.</li>
1976+
* </ul>
1977+
*
1978+
* @param mapExpr The expression representing the map.
1979+
* @param key The key to set. Must be an expression representing a string.
1980+
* @param value The value to set.
1981+
* @param moreKeyValues Additional key-value pairs to set.
1982+
* @return A new {@link Expression} representing the map with the entries set.
1983+
*/
1984+
@BetaApi
1985+
public static Expression mapSet(
1986+
Expression mapExpr, Expression key, Expression value, Expression... moreKeyValues) {
1987+
ImmutableList.Builder<Expression> builder = ImmutableList.builder();
1988+
builder.add(mapExpr);
1989+
builder.add(key);
1990+
builder.add(value);
1991+
builder.add(moreKeyValues);
1992+
return new FunctionExpression("map_set", builder.build());
1993+
}
1994+
1995+
/**
1996+
* Creates an expression that returns a new map with the specified entries added or updated.
1997+
*
1998+
* <ul>
1999+
* <li>Only performs shallow updates to the map.</li>
2000+
* <li>Setting a value to {@code null} will retain the key with a {@code null} value. To remove a
2001+
* key entirely, use {@code mapRemove}.</li>
2002+
* </ul>
2003+
*
2004+
* @param mapField The map field to set entries in.
2005+
* @param key The key to set.
2006+
* @param value The value to set.
2007+
* @param moreKeyValues Additional key-value pairs to set.
2008+
* @return A new {@link Expression} representing the map with the entries set.
2009+
*/
2010+
@BetaApi
2011+
public static Expression mapSet(
2012+
Expression mapExpr, String key, Object value, Object... moreKeyValues) {
2013+
return mapSet(
2014+
mapExpr,
2015+
constant(key),
2016+
toExprOrConstant(value),
2017+
toArrayOfExprOrConstant(moreKeyValues).toArray(new Expression[0]));
2018+
}
2019+
2020+
/**
2021+
* Creates an expression that returns a new map with the specified entries added or updated.
2022+
*
2023+
* <ul>
2024+
* <li>Only performs shallow updates to the map.</li>
2025+
* <li>Setting a value to {@code null} will retain the key with a {@code null} value. To remove a
2026+
* key entirely, use {@code mapRemove}.</li>
2027+
* </ul>
2028+
*
2029+
* @param mapField The map field to set entries in.
2030+
* @param key The key to set. Must be an expression representing a string.
2031+
* @param value The value to set.
2032+
* @param moreKeyValues Additional key-value pairs to set.
2033+
* @return A new {@link Expression} representing the map with the entries set.
2034+
*/
2035+
@BetaApi
2036+
public static Expression mapSet(
2037+
String mapField, Expression key, Expression value, Expression... moreKeyValues) {
2038+
return mapSet(field(mapField), key, value, moreKeyValues);
2039+
}
2040+
2041+
/**
2042+
* Creates an expression that returns a new map with the specified entries added or updated.
2043+
*
2044+
* <ul>
2045+
* <li>Only performs shallow updates to the map.</li>
2046+
* <li>Setting a value to {@code null} will retain the key with a {@code null} value. To remove a
2047+
* key entirely, use {@code mapRemove}.</li>
2048+
* </ul>
2049+
*
2050+
* @param mapField The map field to set entries in.
2051+
* @param key The key to set. Must be an expression representing a string.
2052+
* @param value The value to set.
2053+
* @param moreKeyValues Additional key-value pairs to set.
2054+
* @return A new {@link Expression} representing the map with the entries set.
2055+
*/
2056+
@BetaApi
2057+
public static Expression mapSet(
2058+
String mapField, String key, Object value, Object... moreKeyValues) {
2059+
return mapSet(field(mapField), key, value, moreKeyValues);
2060+
}
2061+
2062+
/**
2063+
* Creates an expression that returns the keys of a map.
2064+
*
2065+
* @param mapExpr The map expression to get the keys of.
2066+
* @return A new {@link Expression} representing the keys of the map.
2067+
*/
2068+
@BetaApi
2069+
public static Expression mapKeys(Expression mapExpr) {
2070+
return new FunctionExpression("map_keys", ImmutableList.of(mapExpr));
2071+
}
2072+
2073+
/**
2074+
* Creates an expression that returns the keys of a map.
2075+
*
2076+
* @param mapField The map field to get the keys of.
2077+
* @return A new {@link Expression} representing the keys of the map.
2078+
*/
2079+
@BetaApi
2080+
public static Expression mapKeys(String mapField) {
2081+
return mapKeys(field(mapField));
2082+
}
2083+
2084+
/**
2085+
* Creates an expression that returns the values of a map.
2086+
*
2087+
* <p>While the backend generally preserves insertion order, relying on the order of the output
2088+
* array is not guaranteed and should be avoided.
2089+
*
2090+
* @param mapExpr The expression representing the map to get the values of.
2091+
* @return A new {@link Expression} representing the values of the map.
2092+
*/
2093+
@BetaApi
2094+
public static Expression mapValues(Expression mapExpr) {
2095+
return new FunctionExpression("map_values", ImmutableList.of(mapExpr));
2096+
}
2097+
2098+
/**
2099+
* Creates an expression that returns the values of a map.
2100+
*
2101+
* @param mapField The map field to get the values of.
2102+
* @return A new {@link Expression} representing the values of the map.
2103+
*/
2104+
@BetaApi
2105+
public static Expression mapValues(String mapField) {
2106+
return mapValues(field(mapField));
2107+
}
2108+
2109+
/**
2110+
* Creates an expression that returns the entries of a map as an array of maps, where each map
2111+
* contains a "k" property for the key and a "v" property for the value.
2112+
*
2113+
* <p>While the backend generally preserves insertion order, relying on the order of the output
2114+
* array is not guaranteed and should be avoided.
2115+
*
2116+
* @param mapExpr The expression representing the map to get the entries of.
2117+
* @return A new {@link Expression} representing the entries of the map.
2118+
*/
2119+
@BetaApi
2120+
public static Expression mapEntries(Expression mapExpr) {
2121+
return new FunctionExpression("map_entries", ImmutableList.of(mapExpr));
2122+
}
2123+
2124+
/**
2125+
* Creates an expression that returns the entries of a map as an array of maps.
2126+
*
2127+
* @param mapField The map field to get the entries of.
2128+
* @return A new {@link Expression} representing the entries of the map.
2129+
*/
2130+
@BetaApi
2131+
public static Expression mapEntries(String mapField) {
2132+
return mapEntries(field(mapField));
2133+
}
2134+
19582135
/**
19592136
* Creates an expression that reverses a string, blob, or array.
19602137
*
@@ -4376,6 +4553,80 @@ public final Expression mapRemove(String key) {
43764553
return mapRemove(this, key);
43774554
}
43784555

4556+
/**
4557+
* Creates an expression that returns a new map with the specified entries added or updated.
4558+
*
4559+
* <p>Note that {@code mapSet} only performs shallow updates to the map. Setting a value to {@code
4560+
* null} will retain the key with a {@code null} value. To remove a key entirely, use {@code
4561+
* mapRemove}.
4562+
*
4563+
* @param key The key to set.
4564+
* @param value The value to set.
4565+
* @param moreKeyValues Additional key-value pairs to set.
4566+
* @return A new {@link Expression} representing the map with the entries set.
4567+
*/
4568+
@BetaApi
4569+
public final Expression mapSet(Expression key, Expression value, Expression... moreKeyValues) {
4570+
return mapSet(this, key, value, moreKeyValues);
4571+
}
4572+
4573+
/**
4574+
* Creates an expression that returns a new map with the specified entries added or updated.
4575+
*
4576+
* @param key The key to set.
4577+
* @param value The value to set.
4578+
* @param moreKeyValues Additional key-value pairs to set.
4579+
* @return A new {@link Expression} representing the map with the entries set.
4580+
*/
4581+
@BetaApi
4582+
public final Expression mapSet(String key, Object value, Object... moreKeyValues) {
4583+
return mapSet(
4584+
this,
4585+
constant(key),
4586+
toExprOrConstant(value),
4587+
toArrayOfExprOrConstant(moreKeyValues).toArray(new Expression[0]));
4588+
}
4589+
4590+
/**
4591+
* Creates an expression that returns the keys of this map expression.
4592+
*
4593+
* <p>While the backend generally preserves insertion order, relying on the order of the output
4594+
* array is not guaranteed and should be avoided.
4595+
*
4596+
* @return A new {@link Expression} representing the keys of the map.
4597+
*/
4598+
@BetaApi
4599+
public final Expression mapKeys() {
4600+
return mapKeys(this);
4601+
}
4602+
4603+
/**
4604+
* Creates an expression that returns the values of this map expression.
4605+
*
4606+
* <p>While the backend generally preserves insertion order, relying on the order of the output
4607+
* array is not guaranteed and should be avoided.
4608+
*
4609+
* @return A new {@link Expression} representing the values of the map.
4610+
*/
4611+
@BetaApi
4612+
public final Expression mapValues() {
4613+
return mapValues(this);
4614+
}
4615+
4616+
/**
4617+
* Creates an expression that returns the entries of this map expression as an array of maps, where
4618+
* each map contains a "k" property for the key and a "v" property for the value.
4619+
*
4620+
* <p>While the backend generally preserves insertion order, relying on the order of the output
4621+
* array is not guaranteed and should be avoided.
4622+
*
4623+
* @return A new {@link Expression} representing the entries of the map.
4624+
*/
4625+
@BetaApi
4626+
public final Expression mapEntries() {
4627+
return mapEntries(this);
4628+
}
4629+
43794630
/**
43804631
* Creates an expression that reverses this expression, which must be a string, blob, or array.
43814632
*

0 commit comments

Comments
 (0)