@@ -1738,6 +1738,209 @@ public void testMapGet() {
17381738 ImmutableMap .of ("hugoAward" , true , "title" , "Dune" ));
17391739 }
17401740
1741+ @ Test
1742+ public void testMapSet () {
1743+ assumeFalse ("Map functions are not supported against the emulator." , isRunningAgainstEmulator ());
1744+
1745+ Map <String , Object > docData = new HashMap <>();
1746+ docData .put ("existingField" , ImmutableMap .of ("foo" , 1L ));
1747+
1748+ Task <Pipeline .Snapshot > execute =
1749+ firestore
1750+ .pipeline ()
1751+ .collection (randomCol )
1752+ .replaceWith (Expression .map (docData ))
1753+ .limit (1 )
1754+ .select (
1755+ Expression .mapSet ("existingField" , "bar" , 2 ).alias ("modifiedField" ),
1756+ Expression .mapSet (Expression .map (ImmutableMap .of ()), "a" , 1 ).alias ("simple" ),
1757+ Expression .mapSet (Expression .map (ImmutableMap .of ("a" , 1 )), "b" , 2 ).alias ("add" ),
1758+ Expression .mapSet (Expression .map (ImmutableMap .of ("a" , 1 )), "a" , 2 ).alias ("overwrite" ),
1759+ Expression .mapSet (Expression .map (ImmutableMap .of ("a" , 1 , "b" , 2 )), "a" , 3 , "c" , 4 )
1760+ .alias ("multi" ),
1761+ Expression .mapSet (
1762+ Expression .map (ImmutableMap .of ("a" , 1 )), "a" , field ("non_existent" ))
1763+ .alias ("remove" ),
1764+ Expression .mapSet (Expression .map (ImmutableMap .of ("a" , 1 )), "b" , null ).alias ("setNull" ),
1765+ Expression .mapSet (
1766+ Expression .map (ImmutableMap .of ("a" , ImmutableMap .of ("b" , 1 ))), "a.b" , 2 )
1767+ .alias ("setDotted" ),
1768+ Expression .mapSet (Expression .map (ImmutableMap .of ()), "" , "empty" ).alias ("setEmptyKey" ),
1769+ Expression .mapSet (
1770+ Expression .map (ImmutableMap .of ("a" , 1 )),
1771+ "b" ,
1772+ Expression .add (constant (1 ), constant (2 )))
1773+ .alias ("setExprVal" ),
1774+ Expression .mapSet (
1775+ Expression .map (ImmutableMap .of ()), "obj" , ImmutableMap .of ("hidden" , true ))
1776+ .alias ("setNestedMap" ),
1777+ Expression .mapSet (Expression .map (ImmutableMap .of ()), "~!@#$%^&*()_+" , "special" )
1778+ .alias ("setSpecialChars" ),
1779+ field ("existingField" ).mapSet ("instanceKey" , 100 ).alias ("instanceSetField" ),
1780+ Expression .map (ImmutableMap .of ("x" , 1 ))
1781+ .mapSet (constant ("y" ), constant (2 ))
1782+ .alias ("instanceSetConstant" ))
1783+ .execute ();
1784+
1785+ List <PipelineResult > resultList = waitFor (execute ).getResults ();
1786+ assertThat (resultList ).isNotEmpty ();
1787+ Map <String , Object > data = resultList .get (0 ).getData ();
1788+
1789+ assertThat ((Map <?, ?>) data .get ("modifiedField" )).containsExactly ("foo" , 1L , "bar" , 2L );
1790+ assertThat ((Map <?, ?>) data .get ("simple" )).containsExactly ("a" , 1L );
1791+ assertThat ((Map <?, ?>) data .get ("add" )).containsExactly ("a" , 1L , "b" , 2L );
1792+ assertThat ((Map <?, ?>) data .get ("overwrite" )).containsExactly ("a" , 2L );
1793+ assertThat ((Map <?, ?>) data .get ("multi" )).containsExactly ("a" , 3L , "b" , 2L , "c" , 4L );
1794+ assertThat ((Map <?, ?>) data .get ("remove" )).isEmpty ();
1795+ assertThat ((Map <?, ?>) data .get ("setNull" )).containsExactly ("a" , 1L , "b" , null );
1796+
1797+ Map <?, ?> setDotted = (Map <?, ?>) data .get ("setDotted" );
1798+ assertThat (setDotted ).containsEntry ("a.b" , 2L );
1799+ assertThat ((Map <?, ?>) setDotted .get ("a" )).containsExactly ("b" , 1L );
1800+
1801+ assertThat ((Map <?, ?>) data .get ("setEmptyKey" )).containsExactly ("" , "empty" );
1802+ assertThat ((Map <?, ?>) data .get ("setExprVal" )).containsExactly ("a" , 1L , "b" , 3L );
1803+ assertThat ((Map <?, ?>) data .get ("setNestedMap" ))
1804+ .isEqualTo (ImmutableMap .of ("obj" , ImmutableMap .of ("hidden" , true )));
1805+ assertThat ((Map <?, ?>) data .get ("setSpecialChars" )).containsExactly ("~!@#$%^&*()_+" , "special" );
1806+
1807+ assertThat ((Map <?, ?>) data .get ("instanceSetField" ))
1808+ .containsExactly ("foo" , 1L , "instanceKey" , 100L );
1809+ assertThat ((Map <?, ?>) data .get ("instanceSetConstant" )).containsExactly ("x" , 1L , "y" , 2L );
1810+ }
1811+
1812+ @ Test
1813+ public void testMapKeys () {
1814+ assumeFalse ("Map functions are not supported against the emulator." , isRunningAgainstEmulator ());
1815+
1816+ Map <String , Object > docData = new HashMap <>();
1817+ docData .put ("existingField" , ImmutableMap .of ("foo" , 1L ));
1818+
1819+ Task <Pipeline .Snapshot > execute =
1820+ firestore
1821+ .pipeline ()
1822+ .collection (randomCol )
1823+ .replaceWith (Expression .map (docData ))
1824+ .limit (1 )
1825+ .select (
1826+ Expression .mapKeys ("existingField" ).alias ("existingKeys" ),
1827+ Expression .mapKeys (Expression .map (ImmutableMap .of ("a" , 1 , "b" , 2 ))).alias ("keys" ),
1828+ Expression .mapKeys (Expression .map (ImmutableMap .of ())).alias ("empty_keys" ),
1829+ Expression .mapKeys (
1830+ Expression .map (ImmutableMap .of ("a" , ImmutableMap .of ("nested" , true ))))
1831+ .alias ("nested_keys" ),
1832+ field ("existingField" ).mapKeys ().alias ("instanceExistingKeys" ),
1833+ Expression .map (ImmutableMap .of ("x" , 10 , "y" , 20 )).mapKeys ().alias ("instanceKeys" ))
1834+ .execute ();
1835+
1836+ List <PipelineResult > resultList = waitFor (execute ).getResults ();
1837+ assertThat (resultList ).isNotEmpty ();
1838+ Map <String , Object > data = resultList .get (0 ).getData ();
1839+
1840+ assertThat ((List <?>) data .get ("existingKeys" )).containsExactly ("foo" );
1841+ assertThat ((List <?>) data .get ("keys" )).containsExactly ("a" , "b" );
1842+ assertThat ((List <?>) data .get ("empty_keys" )).isEmpty ();
1843+ assertThat ((List <?>) data .get ("nested_keys" )).containsExactly ("a" );
1844+
1845+ assertThat ((List <?>) data .get ("instanceExistingKeys" )).containsExactly ("foo" );
1846+ assertThat ((List <?>) data .get ("instanceKeys" )).containsExactly ("x" , "y" );
1847+ }
1848+
1849+ @ Test
1850+ public void testMapValues () {
1851+ assumeFalse ("Map functions are not supported against the emulator." , isRunningAgainstEmulator ());
1852+
1853+ Map <String , Object > docData = new HashMap <>();
1854+ docData .put ("existingField" , ImmutableMap .of ("foo" , 1L ));
1855+
1856+ Task <Pipeline .Snapshot > execute =
1857+ firestore
1858+ .pipeline ()
1859+ .collection (randomCol )
1860+ .replaceWith (Expression .map (docData ))
1861+ .limit (1 )
1862+ .select (
1863+ Expression .mapValues ("existingField" ).alias ("existingValues" ),
1864+ Expression .mapValues (Expression .map (ImmutableMap .of ("a" , 1 , "b" , 2 ))).alias ("values" ),
1865+ Expression .mapValues (Expression .map (ImmutableMap .of ())).alias ("empty_values" ),
1866+ Expression .mapValues (
1867+ Expression .map (ImmutableMap .of ("a" , ImmutableMap .of ("nested" , true ))))
1868+ .alias ("nested_values" ),
1869+ field ("existingField" ).mapValues ().alias ("instanceExistingValues" ),
1870+ Expression .map (ImmutableMap .of ("x" , 10 , "y" , 20 )).mapValues ().alias ("instanceValues" ))
1871+ .execute ();
1872+
1873+ List <PipelineResult > resultList = waitFor (execute ).getResults ();
1874+ assertThat (resultList ).isNotEmpty ();
1875+ Map <String , Object > data = resultList .get (0 ).getData ();
1876+
1877+ assertThat ((List <?>) data .get ("existingValues" )).containsExactly (1L );
1878+ assertThat ((List <?>) data .get ("values" )).containsExactly (1L , 2L );
1879+ assertThat ((List <?>) data .get ("empty_values" )).isEmpty ();
1880+ assertThat ((List <?>) data .get ("nested_values" ))
1881+ .containsExactly (ImmutableMap .of ("nested" , true ));
1882+
1883+ assertThat ((List <?>) data .get ("instanceExistingValues" )).containsExactly (1L );
1884+ assertThat ((List <?>) data .get ("instanceValues" )).containsExactly (10L , 20L );
1885+ }
1886+
1887+ @ Test
1888+ public void testMapEntries () {
1889+ assumeFalse ("Map functions are not supported against the emulator." , isRunningAgainstEmulator ());
1890+
1891+ Map <String , Object > docData = new HashMap <>();
1892+ docData .put ("existingField" , ImmutableMap .of ("foo" , 1L ));
1893+
1894+ Task <Pipeline .Snapshot > execute =
1895+ firestore
1896+ .pipeline ()
1897+ .collection (randomCol )
1898+ .replaceWith (Expression .map (docData ))
1899+ .limit (1 )
1900+ .select (
1901+ Expression .mapEntries ("existingField" ).alias ("existingEntries" ),
1902+ Expression .mapEntries (Expression .map (ImmutableMap .of ("a" , 1 , "b" , 2 )))
1903+ .alias ("entries" ),
1904+ Expression .mapEntries (Expression .map (ImmutableMap .of ())).alias ("empty_entries" ),
1905+ Expression .mapEntries (
1906+ Expression .map (ImmutableMap .of ("a" , ImmutableMap .of ("nested" , true ))))
1907+ .alias ("nested_entries" ),
1908+ field ("existingField" ).mapEntries ().alias ("instanceExistingEntries" ),
1909+ Expression .map (ImmutableMap .of ("x" , 10 , "y" , 20 ))
1910+ .mapEntries ()
1911+ .alias ("instanceEntries" ))
1912+ .execute ();
1913+
1914+ List <PipelineResult > resultList = waitFor (execute ).getResults ();
1915+ assertThat (resultList ).isNotEmpty ();
1916+ Map <String , Object > data = resultList .get (0 ).getData ();
1917+
1918+ assertThat ((List <?>) data .get ("existingEntries" ))
1919+ .containsExactly (ImmutableMap .of ("k" , "foo" , "v" , 1L ));
1920+
1921+ @ SuppressWarnings ("unchecked" )
1922+ List <Map <String , Object >> entries = (List <Map <String , Object >>) data .get ("entries" );
1923+ assertThat (entries ).hasSize (2 );
1924+
1925+ // Map entry order is not guaranteed, so we check containment instead of strict ordering
1926+ assertThat (entries ).contains (ImmutableMap .of ("k" , "a" , "v" , 1L ));
1927+ assertThat (entries ).contains (ImmutableMap .of ("k" , "b" , "v" , 2L ));
1928+
1929+ assertThat ((List <?>) data .get ("empty_entries" )).isEmpty ();
1930+ assertThat ((List <?>) data .get ("nested_entries" ))
1931+ .containsExactly (ImmutableMap .of ("k" , "a" , "v" , ImmutableMap .of ("nested" , true )));
1932+
1933+ assertThat ((List <?>) data .get ("instanceExistingEntries" ))
1934+ .containsExactly (ImmutableMap .of ("k" , "foo" , "v" , 1L ));
1935+
1936+ @ SuppressWarnings ("unchecked" )
1937+ List <Map <String , Object >> instanceEntries =
1938+ (List <Map <String , Object >>) data .get ("instanceEntries" );
1939+ assertThat (instanceEntries ).hasSize (2 );
1940+ assertThat (instanceEntries ).contains (ImmutableMap .of ("k" , "x" , "v" , 10L ));
1941+ assertThat (instanceEntries ).contains (ImmutableMap .of ("k" , "y" , "v" , 20L ));
1942+ }
1943+
17411944 @ Test
17421945 public void testDistanceFunctions () {
17431946 double [] sourceVector = {0.1 , 0.1 };
0 commit comments