Skip to content

Commit c95e038

Browse files
authored
feat(firestore): support array functions (#16128)
Supports the following: * array_first * array_last * array_first_n * array_last_n * array_maximum * array_maximum_n * array_minimum * array_minimum_n * array_slice * array_index_of * array_index_of_all * ~~array_transform (need to check for ref impl when it's ready - docstring, and sep methods or not)~~ * ~~array_filter (need to check for ref impl when it's ready - docstring, and sep methods or not)~~
1 parent 8aa697a commit c95e038

File tree

3 files changed

+679
-1
lines changed

3 files changed

+679
-1
lines changed

packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_expressions.py

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,6 +1728,202 @@ def last(self) -> "Expression":
17281728
"""
17291729
return AggregateFunction("last", [self])
17301730

1731+
@expose_as_static
1732+
def array_first(self) -> "Expression":
1733+
"""Creates an expression that returns the first element of an array.
1734+
1735+
Example:
1736+
>>> # Select the first element of array 'colors'
1737+
>>> Field.of("colors").array_first()
1738+
1739+
Returns:
1740+
A new `Expression` representing the first element of the array.
1741+
"""
1742+
return FunctionExpression("array_first", [self])
1743+
1744+
@expose_as_static
1745+
def array_last(self) -> "Expression":
1746+
"""Creates an expression that returns the last element of an array.
1747+
1748+
Example:
1749+
>>> # Select the last element of array 'colors'
1750+
>>> Field.of("colors").array_last()
1751+
1752+
Returns:
1753+
A new `Expression` representing the last element of the array.
1754+
"""
1755+
return FunctionExpression("array_last", [self])
1756+
1757+
@expose_as_static
1758+
def array_first_n(self, n: int | "Expression") -> "Expression":
1759+
"""Creates an expression that returns the first `n` elements of an array.
1760+
1761+
Example:
1762+
>>> # Select the first 2 elements of array 'colors'
1763+
>>> Field.of("colors").array_first_n(2)
1764+
1765+
Returns:
1766+
A new `Expression` representing the first `n` elements of the array.
1767+
"""
1768+
return FunctionExpression(
1769+
"array_first_n", [self, self._cast_to_expr_or_convert_to_constant(n)]
1770+
)
1771+
1772+
@expose_as_static
1773+
def array_last_n(self, n: int | "Expression") -> "Expression":
1774+
"""Creates an expression that returns the last `n` elements of an array.
1775+
1776+
Example:
1777+
>>> # Select the last 2 elements of array 'colors'
1778+
>>> Field.of("colors").array_last_n(2)
1779+
1780+
Returns:
1781+
A new `Expression` representing the last `n` elements of the array.
1782+
"""
1783+
return FunctionExpression(
1784+
"array_last_n", [self, self._cast_to_expr_or_convert_to_constant(n)]
1785+
)
1786+
1787+
@expose_as_static
1788+
def array_maximum(self) -> "Expression":
1789+
"""Creates an expression that returns the maximum element of an array.
1790+
1791+
Example:
1792+
>>> # Select the maximum element of array 'scores'
1793+
>>> Field.of("scores").array_maximum()
1794+
1795+
Returns:
1796+
A new `Expression` representing the maximum element of the array.
1797+
"""
1798+
return FunctionExpression(
1799+
"maximum", [self], infix_name_override="array_maximum"
1800+
)
1801+
1802+
@expose_as_static
1803+
def array_minimum(self) -> "Expression":
1804+
"""Creates an expression that returns the minimum element of an array.
1805+
1806+
Example:
1807+
>>> # Select the minimum element of array 'scores'
1808+
>>> Field.of("scores").array_minimum()
1809+
1810+
Returns:
1811+
A new `Expression` representing the minimum element of the array.
1812+
"""
1813+
return FunctionExpression(
1814+
"minimum", [self], infix_name_override="array_minimum"
1815+
)
1816+
1817+
@expose_as_static
1818+
def array_maximum_n(self, n: int | "Expression") -> "Expression":
1819+
"""Creates an expression that returns the maximum `n` elements of an array.
1820+
1821+
Example:
1822+
>>> # Select the maximum 2 elements of array 'scores'
1823+
>>> Field.of("scores").array_maximum_n(2)
1824+
1825+
Note:
1826+
Returns the n largest non-null elements in the array, in descending
1827+
order. This does not use a stable sort, meaning the order of equivalent
1828+
elements is undefined.
1829+
1830+
Returns:
1831+
A new `Expression` representing the maximum `n` elements of the array.
1832+
"""
1833+
return FunctionExpression(
1834+
"maximum_n",
1835+
[self, self._cast_to_expr_or_convert_to_constant(n)],
1836+
infix_name_override="array_maximum_n",
1837+
)
1838+
1839+
@expose_as_static
1840+
def array_minimum_n(self, n: int | "Expression") -> "Expression":
1841+
"""Creates an expression that returns the minimum `n` elements of an array.
1842+
1843+
Example:
1844+
>>> # Select the minimum 2 elements of array 'scores'
1845+
>>> Field.of("scores").array_minimum_n(2)
1846+
1847+
Note:
1848+
Returns the n smallest non-null elements in the array, in ascending
1849+
order. This does not use a stable sort, meaning the order of equivalent
1850+
elements is undefined.
1851+
1852+
Returns:
1853+
A new `Expression` representing the minimum `n` elements of the array.
1854+
"""
1855+
return FunctionExpression(
1856+
"minimum_n",
1857+
[self, self._cast_to_expr_or_convert_to_constant(n)],
1858+
infix_name_override="array_minimum_n",
1859+
)
1860+
1861+
@expose_as_static
1862+
def array_slice(
1863+
self, offset: int | "Expression", length: int | "Expression" | None = None
1864+
) -> "Expression":
1865+
"""Creates an expression that returns a slice of an array starting from the specified
1866+
offset with a given length.
1867+
1868+
Example:
1869+
>>> # Slice array 'scores' starting at index 1 with length 2
1870+
>>> Field.of("scores").array_slice(1, 2)
1871+
1872+
Args:
1873+
offset: the 0-based index of the first element to include.
1874+
length: The number of elements to include in the slice. If omitted, slices to the end.
1875+
1876+
Returns:
1877+
A new `Expression` representing the slice of the array.
1878+
"""
1879+
args = [self, self._cast_to_expr_or_convert_to_constant(offset)]
1880+
if length is not None:
1881+
args.append(self._cast_to_expr_or_convert_to_constant(length))
1882+
return FunctionExpression("array_slice", args)
1883+
1884+
@expose_as_static
1885+
def array_index_of(self, search: "Expression" | CONSTANT_TYPE) -> "Expression":
1886+
"""Creates an expression that returns the first index of the search value in the array,
1887+
or -1 if not found.
1888+
1889+
Example:
1890+
>>> # Get the index of "comedy" in the 'tags' array
1891+
>>> Field.of("tags").array_index_of("comedy")
1892+
1893+
Args:
1894+
search: An expression evaluating to the value to search for.
1895+
1896+
Returns:
1897+
A new `Expression` representing the index.
1898+
"""
1899+
return FunctionExpression(
1900+
"array_index_of",
1901+
[
1902+
self,
1903+
self._cast_to_expr_or_convert_to_constant(search),
1904+
self._cast_to_expr_or_convert_to_constant("first"),
1905+
],
1906+
)
1907+
1908+
@expose_as_static
1909+
def array_index_of_all(self, search: "Expression" | CONSTANT_TYPE) -> "Expression":
1910+
"""Creates an expression that returns all indices of a value in an array.
1911+
1912+
Example:
1913+
>>> # Get all indices of "comedy" in the 'tags' array
1914+
>>> Field.of("tags").array_index_of_all("comedy")
1915+
1916+
Args:
1917+
search: An expression evaluating to the value to search for.
1918+
1919+
Returns:
1920+
A new `Expression` representing the indices.
1921+
"""
1922+
return FunctionExpression(
1923+
"array_index_of_all",
1924+
[self, self._cast_to_expr_or_convert_to_constant(search)],
1925+
)
1926+
17311927
@expose_as_static
17321928
def unix_micros_to_timestamp(self) -> "Expression":
17331929
"""Creates an expression that converts a number of microseconds since the epoch (1970-01-01

0 commit comments

Comments
 (0)