{"id":13092,"date":"2022-04-20T10:22:45","date_gmt":"2022-04-20T17:22:45","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=13092"},"modified":"2025-06-13T23:34:37","modified_gmt":"2025-06-14T06:34:37","slug":"creating-python-and-javascript-user-defined-functions-for-geospatial-queries","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/","title":{"rendered":"Cria\u00e7\u00e3o de fun\u00e7\u00f5es definidas pelo usu\u00e1rio em Python e JavaScript para consultas geoespaciais"},"content":{"rendered":"<p><span style=\"font-weight: 400\">As consultas SQL++ podem acessar os dados armazenados no cluster do Couchbase de v\u00e1rias maneiras. H\u00e1 situa\u00e7\u00f5es em que ter a l\u00f3gica de neg\u00f3cios como parte de suas consultas de dados tamb\u00e9m pode ser ben\u00e9fico. O SQL++ oferece suporte a isso com as Fun\u00e7\u00f5es Definidas pelo Usu\u00e1rio (UDFs) que est\u00e3o dispon\u00edveis desde <\/span><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/n1ql-user-defined-functions\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">Couchbase 7.0<\/span><\/a><span style=\"font-weight: 400\">.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">Nesta postagem do blog, criamos uma UDF em JavaScript que consulta pontos a partir da localiza\u00e7\u00e3o de um usu\u00e1rio, dinamicamente, usando SQL++. Al\u00e9m disso, realizamos os mesmos c\u00e1lculos de dist\u00e2ncia com uma UDF em Python dentro do <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/analytics\/introduction.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">Servi\u00e7o de an\u00e1lise<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Nosso caso de uso de consulta geoespacial<\/span><\/h2>\n<p><span style=\"font-weight: 400\">Nosso aplicativo gerar\u00e1 pontos de interesse geogr\u00e1fico a partir do nosso banco de dados que est\u00e3o pr\u00f3ximos \u00e0 localiza\u00e7\u00e3o GPS do usu\u00e1rio, semelhante a servi\u00e7os como o Google Maps, mostrado na captura de tela abaixo. Para este exemplo, usaremos o <\/span><a href=\"https:\/\/docs.couchbase.com\/java-sdk\/current\/ref\/travel-app-data-model.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">conjunto de dados de amostra de viagens<\/span><\/a><span style=\"font-weight: 400\"> que est\u00e1 dispon\u00edvel em um bucket de amostra fornecido pelo Couchbase.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Em particular, estamos interessados em ver o <\/span><i><span style=\"font-weight: 400\">marcos hist\u00f3ricos <\/span><\/i><span style=\"font-weight: 400\">e <\/span><i><span style=\"font-weight: 400\">aeroportos <\/span><\/i><span style=\"font-weight: 400\">em torno da localiza\u00e7\u00e3o atual do usu\u00e1rio. Isso n\u00e3o pode ser feito usando uma consulta SQL++ diretamente, pois o c\u00e1lculo da dist\u00e2ncia \u00e9 baseado na localiza\u00e7\u00e3o geogr\u00e1fica em tempo real do usu\u00e1rio. O SQL++ suporta a defini\u00e7\u00e3o de UDFs em JavaScript para executar a l\u00f3gica personalizada nas consultas.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-13094\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image_2022-04-20_102207935-504x1024.png\" alt=\"Map shwoing searhc for local points of interest\" width=\"504\" height=\"1024\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image_2022-04-20_102207935-504x1024.png 504w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image_2022-04-20_102207935-148x300.png 148w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image_2022-04-20_102207935-300x610.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image_2022-04-20_102207935-10x20.png 10w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image_2022-04-20_102207935.png 519w\" sizes=\"auto, (max-width: 504px) 100vw, 504px\" \/><\/p>\n<h2><span style=\"font-weight: 400\">C\u00e1lculo de dist\u00e2ncias a partir de coordenadas de GPS<\/span><\/h2>\n<p><span style=\"font-weight: 400\">H\u00e1 muitas maneiras de calcular a dist\u00e2ncia entre dois conjuntos de coordenadas de GPS. Neste exemplo, calcularemos a dist\u00e2ncia usando a fun\u00e7\u00e3o <\/span><a href=\"https:\/\/en.wikipedia.org\/wiki\/Haversine_formula\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">F\u00f3rmula Haversine<\/span><\/a><span style=\"font-weight: 400\">. Ele fornece a dist\u00e2ncia aproximada entre duas coordenadas de GPS, considerando o caminho como uma esfera em vez de uma dist\u00e2ncia em linha reta.<\/span><\/p>\n<p><span style=\"font-weight: 400\">O c\u00f3digo JavaScript para calcular dist\u00e2ncias geogr\u00e1ficas \u00e9 mostrado neste exemplo:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:js decode:true\">function degreesToRadians(degrees) {\r\n\u00a0\u00a0\u00a0return degrees * Math.PI \/ 180;\r\n\u00a0}\r\n\r\n\u00a0function distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) {\r\n\r\n\u00a0\u00a0\u00a0var earthRadiusKm = 6371;\r\n\u00a0\u00a0\u00a0var dLat = degreesToRadians(lat2-lat1);\r\n\u00a0\u00a0\u00a0var dLon = degreesToRadians(lon2-lon1);\r\n\r\n\u00a0\u00a0\u00a0lat1 = degreesToRadians(lat1);\r\n\u00a0\u00a0\u00a0lat2 = degreesToRadians(lat2);\r\n\r\n\u00a0\u00a0\u00a0var a = Math.sin(dLat\/2) * Math.sin(dLat\/2) +\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Math.sin(dLon\/2) * Math.sin(dLon\/2) * Math.cos(lat1) * Math.cos(lat2);\r\n\u00a0\u00a0\u00a0var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));\r\n\u00a0\u00a0\u00a0return earthRadiusKm * c;\r\n}<\/pre>\n<p><span style=\"font-weight: 400\">Definimos duas fun\u00e7\u00f5es JavaScript - uma que realiza a convers\u00e3o entre graus e radianos e outra que calcula a dist\u00e2ncia em quil\u00f4metros entre as coordenadas de GPS da outra fun\u00e7\u00e3o.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Importa\u00e7\u00e3o de UDFs para o Couchbase<\/span><\/h2>\n<p><span style=\"font-weight: 400\">Essas fun\u00e7\u00f5es JavaScript agora podem ser importadas para o Couchbase usando o <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/createfunction.html#create-function-external\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">API REST<\/span><\/a><span style=\"font-weight: 400\">como mostrado abaixo, com o <\/span><i><span style=\"font-weight: 400\">enrolar <\/span><\/i><span style=\"font-weight: 400\">comando:<\/span><\/p>\n<pre class=\"wrap:true trim-whitespace:false lang:sh decode:true\">curl -v -X POST https:\/\/localhost:8093\/evaluator\/v1\/libraries\/math -u &lt;user&gt;:&lt;password&gt; -d 'function degreesToRadians(degrees) {  \r\n  return degrees * Math.PI \/ 180;\r\n  }\r\n  function distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) {\r\n  var earthRadiusKm = 6371;\r\n  var dLat = degreesToRadians(lat2-lat1);\r\n  var dLon = degreesToRadians(lon2-lon1);\r\n  lat1 = degreesToRadians(lat1);\r\n  lat2 = degreesToRadians(lat2);\r\n  var a = Math.sin(dLat\/2) * Math.sin(dLat\/2) +\r\n    Math.sin(dLon\/2) * Math.sin(dLon\/2) * Math.cos(lat1) * Math.cos(lat2); \r\n  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));\r\n  return earthRadiusKm * c;\r\n}'<\/pre>\n<p><span style=\"font-weight: 400\">Ap\u00f3s essa etapa, o UDF pode ser definido na se\u00e7\u00e3o <strong>Editor de consultas<\/strong>:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:tsql decode:true\">CREATE FUNCTION degreesToRadians(a) LANGUAGE JAVASCRIPT AS \"degreesToRadians\" AT \"math\"\r\n\r\nCREATE FUNCTION distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) LANGUAGE JAVASCRIPT AS \"distanceInKmBetweenEarthCoordinates\" AT \"math\"<\/pre>\n<p><span style=\"font-weight: 400\">Aqui, o <\/span><i><span style=\"font-weight: 400\">matem\u00e1tica<\/span><\/i><span style=\"font-weight: 400\"> refer\u00eancia \u00e9 para o JavaScript <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-rest-api\/functions.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">biblioteca<\/span><\/a><span style=\"font-weight: 400\"> que criamos para avaliar o UDF.<\/span><\/p>\n<p><span style=\"font-weight: 400\">O UDF agora pode ser testado com coordenadas de GPS de amostra no SQL++ usando o <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/execfunction.html\" target=\"_blank\" rel=\"noopener\"><i><span style=\"font-weight: 400\">Executar <\/span><\/i><span style=\"font-weight: 400\">Fun\u00e7\u00e3o<\/span><\/a><span style=\"font-weight: 400\"> conforme mostrado abaixo<\/span><\/p>\n<pre class=\"decode-attributes:false lang:default decode:true\">EXECUTE FUNCTION distanceInKmBetweenEarthCoordinates(51.5, 0, 38.8, -77.1)<\/pre>\n<p><span style=\"font-weight: 400\">Podemos observar que a fun\u00e7\u00e3o funciona como pretendido quando fornecemos as coordenadas de GPS manualmente para a fun\u00e7\u00e3o.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Conectando o UDF aos dados do Couchbase<\/span><\/h2>\n<p><span style=\"font-weight: 400\">No <em>amostra de viagem<\/em> conjunto de dados, temos as coordenadas de GPS do <\/span><i><span style=\"font-weight: 400\">marcos hist\u00f3ricos <\/span><\/i><span style=\"font-weight: 400\">e <\/span><i><span style=\"font-weight: 400\">aeroportos <\/span><\/i><span style=\"font-weight: 400\">juntamente com outros locais de interesse, como <\/span><i><span style=\"font-weight: 400\">hot\u00e9is<\/span><\/i><span style=\"font-weight: 400\">.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Podemos integr\u00e1-los em nossas consultas, como a que est\u00e1 abaixo:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:tsql decode:true\">SELECT distanceInKmBetweenEarthCoordinates(a.geo.lat, a.geo.lon, 51.509865, -0.118092) AS distance,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0a.airportname,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0a.city\r\nFROM `travel-sample`.inventory.airport a\r\nORDER BY distance ASC\r\nLIMIT 10;<\/pre>\n<p><span style=\"font-weight: 400\">Essa consulta retorna uma lista dos dez aeroportos mais pr\u00f3ximos da localiza\u00e7\u00e3o do usu\u00e1rio (<\/span><i><span style=\"font-weight: 400\">51.509865, -0.118092<\/span><\/i><span style=\"font-weight: 400\">). Fornecemos a latitude (<\/span><i><span style=\"font-weight: 400\">a.geo.lat<\/span><\/i><span style=\"font-weight: 400\">) e longitude (<\/span><i><span style=\"font-weight: 400\">a.geo.lon<\/span><\/i><span style=\"font-weight: 400\">)<\/span> <span style=\"font-weight: 400\">que est\u00e3o incorporados nos documentos usando o poder do SQL++.<\/span><\/p>\n<pre class=\"decode-attributes:false lang:js decode:true\">[\r\n\u00a0\u00a0\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"airportname\": \"All Airports\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"distance\": 0.6998675034052988\r\n\u00a0\u00a0\u00a0},\r\n\u00a0\u00a0\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"airportname\": \"Waterloo International\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"distance\": 0.7880158040048914\r\n\u00a0\u00a0\u00a0},\r\n\u00a0\u00a0\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"airportname\": \"London St Pancras\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"distance\": 2.289359875405007\r\n\u00a0\u00a0\u00a0},\r\n\u00a0\u00a0\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"airportname\": \"Euston Station\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"distance\": 2.30782110865356\r\n\u00a0\u00a0\u00a0},\r\n\u00a0\u00a0\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"airportname\": \"St Pancras Railway Station\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"distance\": 2.582290289682563\r\n\u00a0\u00a0\u00a0},\r\n\u00a0\u00a0\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"airportname\": \"Paddington Station\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"distance\": 4.069442660124984\r\n\u00a0\u00a0\u00a0},\r\n\u00a0\u00a0\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"airportname\": \"London Heliport\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"distance\": 6.062824964656381\r\n\u00a0\u00a0\u00a0},\r\n\u00a0\u00a0\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"airportname\": \"Elstree\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"city\": \"Elstree\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"distance\": 8.735152174563803\r\n\u00a0\u00a0\u00a0},\r\n\u00a0\u00a0\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"airportname\": \"City\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"distance\": 12.009592036043564\r\n\u00a0\u00a0\u00a0},\r\n\u00a0\u00a0\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"airportname\": \"London - Kings Cross\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\"distance\": 16.891716659500467\r\n\u00a0\u00a0\u00a0}\r\n\u00a0]<\/pre>\n<p><span style=\"font-weight: 400\">Da mesma forma, podemos calcular os pontos de interesse ao redor do usu\u00e1rio usando a fun\u00e7\u00e3o <\/span><i><span style=\"font-weight: 400\">marco hist\u00f3rico <\/span><\/i><span style=\"font-weight: 400\">em uma dist\u00e2ncia cada vez maior do usu\u00e1rio:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:tsql decode:true\">SELECT distanceInKmBetweenEarthCoordinates(l.geo.lat, l.geo.lon, 51.509865, -0.118092) AS distance,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0l.activity,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0l.city,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0l.content\r\nFROM `travel-sample`.inventory.landmark l\r\nORDER BY distance ASC\r\nLIMIT 10;<\/pre>\n<p><span style=\"font-weight: 400\">Resultados da consulta mostrando pontos de refer\u00eancia pr\u00f3ximos:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:js decode:true\">[\r\n\u00a0{\r\n\u00a0\u00a0\u00a0\"activity\": \"see\",\r\n\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\"content\": \"Somerset House is home to three art galleries:\u00a0 The exceptional '''Courtauld Institute''' displays a collection of 19th and 20th century art, including well-known works by Degas, Matisse and Kandinsky; The Gilbert Collection presents a collection of decorative art; and The Hermitage Rooms, the most recent addition to Somerset House, hosts temporary exhibitions of works on loan from the Hermitage Museum in Saint Petersburg. The central courtyard is filled with fountains in the Summer, but in the Winter, an ice rink is installed, it is very popular, so visitors should book in advance, or expect to wait a long time to skate.\",\r\n\u00a0\u00a0\u00a0\"distance\": 0.10940067520415872\r\n\u00a0},\r\n\u00a0{\r\n\u00a0\u00a0\u00a0\"activity\": \"see\",\r\n\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\"content\": \"Cleopatra's Needle originated in the ancient [[Egypt]]ian city of [[Cairo\/Heliopolis|Heliopolis]], in the Temple of Atum, but the Romans moved it to [[Alexandria]] in 12 BC.\u00a0 In 1819, viceroy Mehemet Ali presented Cleopatra's Needle to the British, commemorating military victories in Egypt, but it remained in Alexandria until 1877 when transportation was arranged to bring it to London.\u00a0 On the voyage, the ship capsized in a storm, killing six crewmembers.\u00a0 Cleopatra's Needle was thought to be lost, but Spanish trawlers found it afloat a few days later, and after some repairs, it arrived in London on 21 Jan 1878. The obelisk is flanked by two faux-sphinxes, which show the effects of bombings of London during World War II.\u00a0 Today, Cleopatra's Needle shows some wear from exposure to London's damp weather.\",\r\n\u00a0\u00a0\u00a0\"distance\": 0.2153782246329736\r\n\u00a0},\r\n\u00a0{\r\n\u00a0\u00a0\u00a0\"activity\": \"buy\",\r\n\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\"content\": \"Daily second-hand book sale near the bank of the Thames. A nice place to just browse for books (classic and modern), maps and prints.\",\r\n\u00a0\u00a0\u00a0\"distance\": 0.329776385402355\r\n\u00a0},\r\n\u00a0{\r\n\u00a0\u00a0\u00a0\"activity\": \"see\",\r\n\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\"content\": \"[[London]] (in [[London\/Covent Garden|Covent Garden]])\",\r\n\u00a0\u00a0\u00a0\"distance\": 0.34889537479151833\r\n\u00a0},\r\n\u00a0{\r\n\u00a0\u00a0\u00a0\"activity\": \"see\",\r\n\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\"content\": \"London's most famous and popular skateboarding area, situated partly underneath Queen Elizabeth Hall along Queen's Walk and the Thames.\u00a0 Also popular with graffiti artists, BMXers and so forth.\",\r\n\u00a0\u00a0\u00a0\"distance\": 0.36487940944981834\r\n\u00a0},\r\n\u00a0{\r\n\u00a0\u00a0\u00a0\"activity\": \"see\",\r\n\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\"content\": \"Tucked under Waterloo Bridge, BFI Southbank, formerly known as the National Film Theatre, pitches itself as the home of film and has three screens showing classic (including silent), foreign language and less mainstream films. Recently redeveloped, it now has a new entrance on Theatre Alley, a shop dedicated to film, an interactive exhibition space and an excellent bar\/restaurant at the back. Visitors can also access the Mediatheque - wind your way through the BFI's extensive film and TV archive for free.\u00a0 Cool bar and restaurant. Tickets are generally available on the spur of the moment.\",\r\n\u00a0\u00a0\u00a0\"distance\": 0.378692262237853\r\n\u00a0},\r\n\u00a0{\r\n\u00a0\u00a0\u00a0\"activity\": \"see\",\r\n\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\"content\": \"Music venue hosting daily performances. | image=Queen Elizabeth Hall.jpg\",\r\n\u00a0\u00a0\u00a0\"distance\": 0.3859430181613397\r\n\u00a0},\r\n\u00a0{\r\n\u00a0\u00a0\u00a0\"activity\": \"drink\",\r\n\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\"content\": \"The antidote to gay bars: a pub-like atmosphere and great music. | image=The Retro Bar.jpg\",\r\n\u00a0\u00a0\u00a0\"distance\": 0.39732030942983415\r\n\u00a0},\r\n\u00a0{\r\n\u00a0\u00a0\u00a0\"activity\": \"see\",\r\n\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\"content\": \"Three large auditoriums, the Olivier, the Lyttelton and the Cottesloe. The Olivier theatre is the largest with an open stage and a fan shaped auditorium around it. This ensures that all seats provide a good view. Most of the more 'popular' productions are put on here as the space provided is much larger than most theatres. The Lyttelton theatre is more traditional with a procenium arc with good views from most seats. The Cottesloe is a small studio theatre, seating around 400. Some tickets will be available on the day, either day seats (arrive before 09:30 and queue) or standby (arrive before 6PM and queue), or you can buy online. Popular shows, especially those around Christmas in the Olivier sell out months in advance. Tickets to The National Theatre are generally better value than most other theatres. There is also the '\u00a310 Travelex' season in the summer that provides a large number (over 100,000 seats a year) at \u00a310. Booking in advance is required for these. There is also an exhibition space in the Lyttelton theatre foyer that frequently holds popular photographic exhibitions. Free jazz is often played in the evening in the ground floor foyer. During summer there is a free daily outdoor festival of performance, music, comedy and cabaret known as Watch This Space. Deckchairs (and artificial grass) are provided to watch on. Free exhibitions. Backstage tours \u00a35. (https:\/\/www.nationaltheatrelondon.com\/tickets\/)\",\r\n\u00a0\u00a0\u00a0\"distance\": 0.42625112040817054\r\n\u00a0},\r\n\u00a0{\r\n\u00a0\u00a0\u00a0\"activity\": \"drink\",\r\n\u00a0\u00a0\u00a0\"city\": \"London\",\r\n\u00a0\u00a0\u00a0\"content\": \"Free nightly music events.\u00a0 The best place to sample underground electro, indie, dub-step and more.\",\r\n\u00a0\u00a0\u00a0\"distance\": 0.4323026974543284\r\n\u00a0}\r\n]<\/pre>\n<p><span style=\"font-weight: 400\">Se executarmos essas consultas para v\u00e1rios usu\u00e1rios ao mesmo tempo, poderemos ter problemas de desempenho, pois estamos usando os recursos de computa\u00e7\u00e3o que fazem parte do cluster do Couchbase.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">Nesses cen\u00e1rios, o Couchbase Analytics pode reduzir o impacto em seu cluster. <\/span><span style=\"font-weight: 400\">O Couchbase Analytics foi projetado para executar com efici\u00eancia consultas complexas em muitos registros. As consultas complexas podem incluir grandes opera\u00e7\u00f5es ad hoc de jun\u00e7\u00e3o, conjunto, agrega\u00e7\u00e3o e agrupamento - qualquer uma delas pode resultar em consultas de longa dura\u00e7\u00e3o, alto uso da CPU, alto consumo de mem\u00f3ria ou lat\u00eancia excessiva da rede devido \u00e0 busca de dados e \u00e0 coordena\u00e7\u00e3o entre n\u00f3s.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Fun\u00e7\u00f5es definidas pelo usu\u00e1rio com o Couchbase Analytics<\/span><\/h2>\n<p><span style=\"font-weight: 400\">O Couchbase Analytics nos permite definir e usar <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/analytics\/appendix_5_python.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">Fun\u00e7\u00f5es definidas pelo usu\u00e1rio em Python<\/span><\/a><span style=\"font-weight: 400\"> mas, no momento da reda\u00e7\u00e3o deste documento, exige que voc\u00ea <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/developer-preview\/preview-mode.html#how-do-i-enable-the-developer-preview-mode\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">ativar o Developer Preview<\/span><\/a><span style=\"font-weight: 400\"> no Couchbase Server. Isso pode ser feito com o seguinte comando:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:sh decode:true\">$ \/opt\/couchbase\/bin\/couchbase-cli enable-developer-preview \\\r\n  --enable -c localhost:8091 -u &lt;username&gt; -p &lt;password&gt;<\/pre>\n<p><span style=\"font-weight: 400\">A pr\u00f3xima etapa \u00e9 criar um pacote Python, localmente, no ambiente de desenvolvimento com o Python UDF. Nesse caso, o UDF \u00e9 um m\u00e9todo para calcular a dist\u00e2ncia entre duas coordenadas de GPS.<\/span><\/p>\n<pre class=\"decode-attributes:false lang:python decode:true\"># distance.py\r\nfrom geopy import distance\r\n\r\nclass distance_calculation:\r\n\u00a0\u00a0\u00a0def calculate_distance(self, lat1, lon1, lat2, lon2) -&gt; float:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"\"\"Calculate Distance using geodesic distance\"\"\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return distance.distance((lat1, lon1), (lat2, lon2)).km<\/pre>\n<p><span style=\"font-weight: 400\">Aqui, calculamos o <\/span><a href=\"https:\/\/en.wikipedia.org\/wiki\/Geodesics_on_an_ellipsoid\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">dist\u00e2ncia geod\u00e9sica<\/span><\/a><span style=\"font-weight: 400\"> (a dist\u00e2ncia mais curta entre pontos ao longo de um caminho curvo) entre as duas coordenadas de GPS com a ajuda de uma biblioteca, <\/span><a href=\"https:\/\/geopy.readthedocs.io\/\" target=\"_blank\" rel=\"noopener\"><i><span style=\"font-weight: 400\">geopia<\/span><\/i><\/a><span style=\"font-weight: 400\">.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Empacotamento do UDF<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Para empacotar a biblioteca, usamos um pacote <\/span><a href=\"https:\/\/shiv.readthedocs.io\/en\/latest\/\" target=\"_blank\" rel=\"noopener\"><i><span style=\"font-weight: 400\">shiv<\/span><\/i><\/a> <span style=\"font-weight: 400\">que pode empacotar o c\u00f3digo junto com seus requisitos para qualquer plataforma. Aqui, estamos usando o Linux, pois o Couchbase Server est\u00e1 sendo executado em um ambiente Linux dentro do Docker.<\/span><\/p>\n<pre class=\"decode-attributes:false lang:sh decode:true\">shiv -o distance.pyz --site-packages . --platform manylinux2010_x86_64 --python-version 39 --only-binary=:all: geopy<\/pre>\n<p><span style=\"font-weight: 400\">Para fazer upload desse pacote bin\u00e1rio com o UDF para o Couchbase, precisamos usar o comando <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/analytics\/rest-library.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">API REST<\/span><\/a><span style=\"font-weight: 400\"> para o servi\u00e7o do Analytics.\u00a0<\/span><\/p>\n<pre class=\"decode-attributes:false lang:sh decode:true\">curl -X POST -u &lt;username&gt;:&lt;password&gt; -F \"type=python\" -F \"data=@.\/distance.pyz\" localhost:8095\/analytics\/library\/Default\/pylib<\/pre>\n<p><span style=\"font-weight: 400\">Isso faz o upload do UDF empacotado para o <\/span><i><span style=\"font-weight: 400\">pylib<\/span><\/i><span style=\"font-weight: 400\"> na biblioteca <\/span><i><span style=\"font-weight: 400\">padr\u00e3o <\/span><\/i><span style=\"font-weight: 400\">escopo (anteriormente <\/span><span style=\"font-weight: 400\">universo de dados<\/span><span style=\"font-weight: 400\">) do ambiente do Analytics. Agora podemos definir o UDF na se\u00e7\u00e3o <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/analytics\/run-query.html#Using_analytics_workbench\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">Workbench de an\u00e1lise<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Essa declara\u00e7\u00e3o de defini\u00e7\u00e3o indica que estamos definindo um UDF chamado <\/span><i><span style=\"font-weight: 400\">dist\u00e2ncia_em_km <\/span><\/i><span style=\"font-weight: 400\">que pode ser chamado a partir da fun\u00e7\u00e3o Python <\/span><i><span style=\"font-weight: 400\">calculate_distance <\/span><\/i><span style=\"font-weight: 400\">definido na classe <\/span><i><span style=\"font-weight: 400\">c\u00e1lculo de dist\u00e2ncia<\/span><\/i><span style=\"font-weight: 400\"> dentro do m\u00f3dulo Python <\/span><i><span style=\"font-weight: 400\">dist\u00e2ncia.<\/span><\/i><\/p>\n<pre class=\"decode-attributes:false lang:tsql decode:true\">CREATE ANALYTICS FUNCTION distance_in_km(lat1, lon1, lat2, lon2) AS \"distance\",\r\n\u00a0\u00a0\"distance_calculation.calculate_distance\" AT pylib;<\/pre>\n<p><span style=\"font-weight: 400\">Agora podemos usar o UDF em nossas consultas do Analytics da mesma forma que usamos o UDF em nossas consultas do SQL++.<\/span><\/p>\n<pre class=\"decode-attributes:false lang:tsql decode:true\">SELECT distance_in_km(51.5, 0, 38.8, -77.1) AS \"distance\"\r\n\r\nRESULTS:\r\n[\r\n\u00a0{\r\n\u00a0\u00a0\u00a0\"distance\": 5933.5299530300545\r\n\u00a0}\r\n]<\/pre>\n<h3><span style=\"font-weight: 400\">Mapeamento de dados do Data Service no Analytics Service<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Para consultar os dados no Data Service a partir do Analytics Service, precisamos <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/analytics\/manage-datasets.html#mapping-collections-from-the-data-service\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">mapa<\/span><\/a><span style=\"font-weight: 400\"> o <\/span><i><span style=\"font-weight: 400\">amostra de viagem<\/span><\/i><span style=\"font-weight: 400\"> cole\u00e7\u00f5es de dados no Analytics que cria uma c\u00f3pia sombra em tempo real dos dados no Data Service no Analytics. Para este exemplo, precisamos mapear as cole\u00e7\u00f5es com dados geogr\u00e1ficos, ou seja, o <\/span><i><span style=\"font-weight: 400\">ponto de refer\u00eancia, aeroporto <\/span><\/i><span style=\"font-weight: 400\">e<\/span><i><span style=\"font-weight: 400\"> hotel<\/span><\/i><span style=\"font-weight: 400\"> cole\u00e7\u00f5es do escopo do invent\u00e1rio no<\/span><i><span style=\"font-weight: 400\"> amostra de viagem<\/span><\/i><span style=\"font-weight: 400\"> balde.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Execu\u00e7\u00e3o do UDF do Analytics nos dados do Couchbase<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Agora, podemos executar as mesmas consultas que est\u00e1vamos executando antes no SQL++, mas com o Analytics Service. Apenas o nome do UDF foi alterado. O restante da interface \u00e9 semelhante ao que t\u00ednhamos com as consultas do SQL++. Os resultados tamb\u00e9m ser\u00e3o semelhantes aos resultados anteriores.<\/span><\/p>\n<pre class=\"decode-attributes:false lang:tsql decode:true\">SELECT distance_in_km(a.geo.lat, a.geo.lon, 51.509865, -0.118092) AS distance,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0a.airportname,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0a.city\r\nFROM `travel-sample`.inventory.airport a\r\nORDER BY distance ASC\r\nLIMIT 10;\r\n\r\nSELECT distance_in_km(l.geo.lat, l.geo.lon, 51.509865, -0.118092) AS distance,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0l.activity,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0l.city,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0l.content\r\nFROM `travel-sample`.inventory.landmark l\r\nORDER BY distance ASC\r\nLIMIT 10;<\/pre>\n<p><span style=\"font-weight: 400\">Essa abordagem \u00e9 adequada quando queremos executar essas consultas sem afetar o <\/span><i><span style=\"font-weight: 400\">Servi\u00e7o de dados<\/span><\/i><span style=\"font-weight: 400\"> que \u00e9 comumente usado para nossos dados transacionais. Os dados s\u00e3o sincronizados entre o <\/span><i><span style=\"font-weight: 400\">Dados <\/span><\/i><span style=\"font-weight: 400\">e o<\/span><i><span style=\"font-weight: 400\"> Servi\u00e7o de an\u00e1lise <\/span><\/i><span style=\"font-weight: 400\">internamente em tempo real no Couchbase.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Resumo<\/span><\/h2>\n<p><span style=\"font-weight: 400\">Nesta postagem do blog, voc\u00ea aprendeu a criar uma fun\u00e7\u00e3o definida pelo usu\u00e1rio (UDF) em JavaScript que calcula as dist\u00e2ncias entre duas coordenadas de GPS. Voc\u00ea viu como importar a UDF para o Couchbase e, em seguida, integr\u00e1-la a uma consulta SQL++ para alimentar aplicativos que poderiam fornecer pontos de interesse em torno de um usu\u00e1rio. Tamb\u00e9m mostramos como voc\u00ea pode executar o mesmo c\u00e1lculo de dist\u00e2ncia em um UDF baseado em Python usando o servi\u00e7o Analytics para reduzir o impacto no cluster transacional do Couchbase.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Para leitura e refer\u00eancia adicionais, consulte os seguintes recursos:<\/span><\/p>\n<ul>\n<li style=\"list-style-type: none\">\n<ul>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/n1ql-user-defined-functions\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">O SQL++ agora oferece suporte a fun\u00e7\u00f5es definidas pelo usu\u00e1rio<\/span><\/a><span style=\"font-weight: 400\">\u00a0(Blog)<\/span><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/docs.couchbase.com\/java-sdk\/current\/ref\/travel-app-data-model.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">Aplicativo de amostra de viagens do Couchbase<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/createfunction.html#create-function-external\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">API REST do Couchbase para criar fun\u00e7\u00f5es<\/span><\/a><span style=\"font-weight: 400\"> (Docs)<\/span><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/docs.couchbase.com\/server\/current\/analytics\/appendix_5_python.html\" target=\"_blank\" rel=\"noopener\">Cria\u00e7\u00e3o de UDFs Python no Couchbase Analytics Service<\/a> (Docs)<\/li>\n<\/ul>\n<\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>SQL++ queries can access data stored in your Couchbase cluster in a variety of ways. There are situations where having the business logic as part of your data queries can also be beneficial. SQL++ supports this with User Defined Functions [&hellip;]<\/p>","protected":false},"author":80878,"featured_media":13093,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[2294,1816,8683,9327,9139,1812],"tags":[1543,8911],"ppma_author":[9543],"class_list":["post-13092","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","category-couchbase-server","category-geospatial","category-javascript","category-python","category-n1ql-query","tag-javascript","tag-udf"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Creating Python and JavaScript User Defined Functions For Geospatial Queries - The Couchbase Blog<\/title>\n<meta name=\"description\" content=\"Create User Defined Functions UDFs in Python and JavaScript to run geospatial queries in Couchbase Analytics and SQL++\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Creating Python and JavaScript User Defined Functions For Geospatial Queries\" \/>\n<meta property=\"og:description\" content=\"Create User Defined Functions UDFs in Python and JavaScript to run geospatial queries in Couchbase Analytics and SQL++\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-04-20T17:22:45+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T06:34:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/couchbase-analytics-sql-user-defined-functions-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1920\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Nithish Raghunandanan\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nithish Raghunandanan\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/\"},\"author\":{\"name\":\"nithishr\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c5a843d75ad78b5b698f59ca6d123af2\"},\"headline\":\"Creating Python and JavaScript User Defined Functions For Geospatial Queries\",\"datePublished\":\"2022-04-20T17:22:45+00:00\",\"dateModified\":\"2025-06-14T06:34:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/\"},\"wordCount\":1127,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/couchbase-analytics-sql-user-defined-functions-scaled.jpg\",\"keywords\":[\"javascript\",\"User Defined Function (UDF)\"],\"articleSection\":[\"Couchbase Analytics\",\"Couchbase Server\",\"Geospatial\",\"JavaScript\",\"Python\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/\",\"name\":\"Creating Python and JavaScript User Defined Functions For Geospatial Queries - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/couchbase-analytics-sql-user-defined-functions-scaled.jpg\",\"datePublished\":\"2022-04-20T17:22:45+00:00\",\"dateModified\":\"2025-06-14T06:34:37+00:00\",\"description\":\"Create User Defined Functions UDFs in Python and JavaScript to run geospatial queries in Couchbase Analytics and SQL++\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/couchbase-analytics-sql-user-defined-functions-scaled.jpg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/couchbase-analytics-sql-user-defined-functions-scaled.jpg\",\"width\":2560,\"height\":1920,\"caption\":\"Create user defined functions in Python and JavaScript\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Creating Python and JavaScript User Defined Functions For Geospatial Queries\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c5a843d75ad78b5b698f59ca6d123af2\",\"name\":\"nithishr\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/63270a592008f9080fe48b7652fe559f\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/03\/image-4.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/03\/image-4.png\",\"caption\":\"nithishr\"},\"description\":\"Nithish is an engineer who loves to build products that solve real-world problems in short spans of time. He has experienced different areas of the industry having worked in diverse companies in Germany and India. Apart from work, he likes to travel and interact and engage with the tech community through Meetups &amp; Hackathons. In his free time, he likes to try stuff out by hacking things together.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/nithishr\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Creating Python and JavaScript User Defined Functions For Geospatial Queries - The Couchbase Blog","description":"Criar fun\u00e7\u00f5es definidas pelo usu\u00e1rio (UDFs) em Python e JavaScript para executar consultas geoespaciais no Couchbase Analytics e no SQL++","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/pt\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/","og_locale":"pt_BR","og_type":"article","og_title":"Creating Python and JavaScript User Defined Functions For Geospatial Queries","og_description":"Create User Defined Functions UDFs in Python and JavaScript to run geospatial queries in Couchbase Analytics and SQL++","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/","og_site_name":"The Couchbase Blog","article_published_time":"2022-04-20T17:22:45+00:00","article_modified_time":"2025-06-14T06:34:37+00:00","og_image":[{"width":2560,"height":1920,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/couchbase-analytics-sql-user-defined-functions-scaled.jpg","type":"image\/jpeg"}],"author":"Nithish Raghunandanan","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Nithish Raghunandanan","Est. reading time":"11 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/"},"author":{"name":"nithishr","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c5a843d75ad78b5b698f59ca6d123af2"},"headline":"Creating Python and JavaScript User Defined Functions For Geospatial Queries","datePublished":"2022-04-20T17:22:45+00:00","dateModified":"2025-06-14T06:34:37+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/"},"wordCount":1127,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/couchbase-analytics-sql-user-defined-functions-scaled.jpg","keywords":["javascript","User Defined Function (UDF)"],"articleSection":["Couchbase Analytics","Couchbase Server","Geospatial","JavaScript","Python","SQL++ \/ N1QL Query"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/","url":"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/","name":"Creating Python and JavaScript User Defined Functions For Geospatial Queries - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/couchbase-analytics-sql-user-defined-functions-scaled.jpg","datePublished":"2022-04-20T17:22:45+00:00","dateModified":"2025-06-14T06:34:37+00:00","description":"Criar fun\u00e7\u00f5es definidas pelo usu\u00e1rio (UDFs) em Python e JavaScript para executar consultas geoespaciais no Couchbase Analytics e no SQL++","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/couchbase-analytics-sql-user-defined-functions-scaled.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/couchbase-analytics-sql-user-defined-functions-scaled.jpg","width":2560,"height":1920,"caption":"Create user defined functions in Python and JavaScript"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/creating-python-and-javascript-user-defined-functions-for-geospatial-queries\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Creating Python and JavaScript User Defined Functions For Geospatial Queries"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c5a843d75ad78b5b698f59ca6d123af2","name":"nithishr","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/63270a592008f9080fe48b7652fe559f","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/03\/image-4.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/03\/image-4.png","caption":"nithishr"},"description":"Nithish \u00e9 um engenheiro que adora criar produtos que resolvam problemas do mundo real em um curto espa\u00e7o de tempo. Ele tem experi\u00eancia em diferentes \u00e1reas do setor, tendo trabalhado em diversas empresas na Alemanha e na \u00cdndia. Al\u00e9m do trabalho, ele gosta de viajar, interagir e se envolver com a comunidade de tecnologia por meio de Meetups e Hackathons. Em seu tempo livre, ele gosta de experimentar coisas, criando coisas.","url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/nithishr\/"}]}},"authors":[{"term_id":9543,"user_id":80878,"is_guest":0,"slug":"nithishr","display_name":"Nithish Raghunandanan","avatar_url":{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/03\/image-4.png","url2x":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/03\/image-4.png"},"author_category":"","last_name":"Raghunandanan","first_name":"Nithish","job_title":"","user_url":"","description":"Nithish \u00e9 um engenheiro que adora criar produtos que resolvam problemas do mundo real em um curto espa\u00e7o de tempo. Ele tem experi\u00eancia em diferentes \u00e1reas do setor, tendo trabalhado em diversas empresas na Alemanha e na \u00cdndia. Al\u00e9m do trabalho, ele gosta de viajar, interagir e se envolver com a comunidade de tecnologia por meio de Meetups e Hackathons. Em seu tempo livre, ele gosta de experimentar coisas, criando coisas."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/13092","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/80878"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=13092"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/13092\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/13093"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=13092"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=13092"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=13092"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=13092"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}