<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ geolocation - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ geolocation - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 26 Jun 2026 22:47:43 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/geolocation/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Use the Geolocation API in JavaScript – with Code Examples ]]>
                </title>
                <description>
                    <![CDATA[ The Geolocation API is a standard API implemented in browsers to retrieve the location of the people who are interacting with a web application. This API enable users to send their location to a web application to enable relevant services, such as se... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-the-javascript-geolocation-api/</link>
                <guid isPermaLink="false">66bd915d621c718d60a31067</guid>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ geolocation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Nathan Sebhastian ]]>
                </dc:creator>
                <pubDate>Mon, 26 Feb 2024 22:34:24 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/02/js-geolocation-api-cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The Geolocation API is a standard API implemented in browsers to retrieve the location of the people who are interacting with a web application.</p>
<p>This API enable users to send their location to a web application to enable relevant services, such as seeking a restaurant or hotel near the user.</p>
<p>In this article, I'm going to show you how to use the Geolocation API with JavaScript and display a user's current location using a map API. </p>
<p>Let's get started!</p>
<h2 id="heading-how-to-access-the-geolocation-api">How to Access the Geolocation API</h2>
<p>Browsers implement the geolocation API in the <code>navigator.geolocation</code> object. You can check if the browser you use supports this API as follows:</p>
<pre><code class="lang-js"><span class="hljs-keyword">if</span> (<span class="hljs-string">'geolocation'</span> <span class="hljs-keyword">in</span> navigator) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Geolocation is Available'</span>);
} <span class="hljs-keyword">else</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Geolocation is NOT Available'</span>);
}
</code></pre>
<p>If the browser replies with 'Geolocation is Available', then you can use the methods of the <code>geolocation</code> object to get the user data.</p>
<p>The Geolocation API is only available under a secure HTTPS context, but modern browsers like Chrome and Firefox allow access to this API from localhost for development purposes.</p>
<p>There are two methods you can use to get user data:</p>
<ul>
<li><code>getCurrentPosition()</code>: Returns the current position of the device.</li>
<li><code>watchPosition()</code>: Observes the position of the device continuously until the watcher is stopped.</li>
</ul>
<p>Both methods above receive 3 arguments as follows:</p>
<ul>
<li><code>success</code>: a callback function for when the geolocation data is retrieved (required).</li>
<li><code>error</code>: a callback function for when the method encounters an error (optional).</li>
<li><code>options</code>: an object defining extra parameters when running the method (optional).</li>
</ul>
<p>When the Geolocation API is accessed for the first time, a permission request will pop up near the URL bar as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/geolocation-permission.png" alt="Image" width="600" height="400" loading="lazy">
<em>Requesting Permission to Access User's Location</em></p>
<p>You might be familiar with the pop up above. When you choose to block the request, then the <code>error</code> callback function will be executed by the API.</p>
<p>Otherwise, the <code>success</code> callback will be executed.</p>
<h2 id="heading-how-to-get-users-current-position">How to Get User's Current Position</h2>
<p>To get the user's current position, you can call the <code>getCurrentPosition()</code> from the <code>navigator.geolocation</code> object as shown below:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">success</span>(<span class="hljs-params">position</span>) </span>{
  <span class="hljs-built_in">console</span>.log(position);
}

navigator.geolocation.getCurrentPosition(success);
</code></pre>
<p>The <code>getCurrentPosition()</code> method will send the <code>position</code> object to the <code>success()</code> function above.</p>
<p>The <code>position</code> object contains the location coordinates and timestamp showing when the location was retrieved. </p>
<p>Below is an example of the <code>position</code> object:</p>
<pre><code class="lang-js">{
  <span class="hljs-attr">coords</span>: {
    <span class="hljs-attr">latitude</span>: <span class="hljs-number">1.314</span>,
    <span class="hljs-attr">longitude</span>: <span class="hljs-number">103.84425</span>
    <span class="hljs-attr">altitude</span>: <span class="hljs-literal">null</span>
  },
  <span class="hljs-attr">timestamp</span>: <span class="hljs-number">1708674456885</span>
}
</code></pre>
<p>Using the latitude and longitude information, you can pinpoint the user's location and provide relevant information and services.</p>
<p>For example, let's see how you can send a request to the <a target="_blank" href="https://www.openstreetmap.org/">OpenStreetMap</a> website and pin the user's current location using the data from Geolocation API.</p>
<p>OpenStreetMap is an open source project providing a free geographic map of the whole earth.</p>
<p>You need to create an HTML document with the following body content:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"getLocation"</span>&gt;</span>Get Location<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"locationResult"</span> <span class="hljs-attr">target</span>=<span class="hljs-string">"_blank"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>When the user clicks on the <em>Get Location</em> button above, we will access the Geolocation API, retrieve the user location, and provide a link to see the user's location on a map.</p>
<p>Next, create a <code>&lt;script&gt;</code> tag before the closing <code>&lt;/body&gt;</code> tag and write the following JavaScript code:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">const</span> locationResult = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#locationResult'</span>);
  <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#getLocation'</span>).addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
    locationResult.textContent = <span class="hljs-string">'Retrieving User Location...'</span>

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">success</span>(<span class="hljs-params">position</span>) </span>{
      <span class="hljs-keyword">let</span> { coords } = position;
      locationResult.textContent = <span class="hljs-string">'See my location on a map'</span>;
      locationResult.href = <span class="hljs-string">`https://www.openstreetmap.org?mlat=<span class="hljs-subst">${coords.latitude}</span>&amp;mlon=<span class="hljs-subst">${coords.longitude}</span>`</span>;
    }

    navigator.geolocation.getCurrentPosition(success);
  });
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>When the button is clicked, we'll run the <code>getCurrentPosition()</code> method and set the <code>href</code> attribute of the <code>&lt;a&gt;</code> tag to the OpenStreetMap website, passing along the <code>latitude</code> and <code>longitude</code> data under the <code>mlat</code> and <code>mlong</code> query string.</p>
<p>Visiting the link would show a map of the current location as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/geolocation-getCurrentPosition.png" alt="OpenStreetMap Using Geolocation API data" width="600" height="400" loading="lazy">
<em>The OpenStreetMap Website Pin On the Latitude and Longitude Data</em></p>
<p>And that's how you get the current location of the user. How to process the location information is up to you.</p>
<p>I've created a website where you can test this functionality at <a target="_blank" href="https://nathansebhastian.github.io/js-geolocation-api/">https://nathansebhastian.github.io/js-geolocation-api/</a></p>
<p>Next, let's learn about the <code>watchPosition()</code> method.</p>
<h2 id="heading-how-to-watch-users-position">How to Watch User's Position</h2>
<p>The <code>watchPosition()</code> method will continue watching the device position when called. It will run the <code>success</code> callback function each time the device location changes.</p>
<p>You can call the method as follows:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">success</span>(<span class="hljs-params">position</span>) </span>{
  <span class="hljs-keyword">const</span> { coords } = position;
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Latitude data: '</span> + coords.latitude);
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Longitude data: '</span> + coords.longitude);
}

navigator.geolocation.watchPosition(success);
</code></pre>
<p>The <code>watchPosition()</code> method returns an ID number that tracks the watcher. If you want to stop the watcher from sending location data, you need to call the <code>clearWatch()</code> method and pass the ID number:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">success</span>(<span class="hljs-params">position</span>) </span>{
  <span class="hljs-keyword">const</span> { coords } = position;
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Latitude data: '</span> + coords.latitude);
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Longitude data: '</span> + coords.longitude);
}

<span class="hljs-comment">// Store the ID number in a variable</span>
<span class="hljs-keyword">const</span> watcherID = navigator.geolocation.watchPosition(success);

<span class="hljs-comment">// Stop the watcher</span>
navigator.geolocation.clearWatch(watcherID);
</code></pre>
<p>And that's all there is to the <code>watchPosition()</code> method.</p>
<h3 id="heading-how-to-add-the-options-object">How to Add the Options Object</h3>
<p>Next, let's take a look at the optional <code>options</code> object that you can pass to <code>getCurrentPosition()</code> and <code>watchPosition()</code> methods.</p>
<p>The <code>options</code> object allows you to customize the behavior of the methods. There are three options you can set:</p>
<ul>
<li><code>enableHighAccuracy</code>: a Boolean value that instructs the method to provide a more accurate position. This will increase power consumption. The default value is <code>false</code>.</li>
<li><code>timeout</code>: a number value representing how long the method waits for a response. The default value is <code>Infinity</code>, which means the method will wait until a location is available.</li>
<li><code>maximumAge</code>: a number value representing how long the Geolocation API can send the previous location data. The default value is <code>0</code>, so the API always returns the latest location. If set to <code>Infinity</code>, then the API will always return the first location data retrieved.</li>
</ul>
<p>You can use the options object when calling the <code>geolocation</code> methods. </p>
<p>For example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> options = {
  <span class="hljs-attr">enableHighAccuracy</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">// enable high accuracy</span>
  <span class="hljs-attr">timeout</span>: <span class="hljs-number">300000</span>, <span class="hljs-comment">// wait for 5 minutes</span>
};

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">success</span>(<span class="hljs-params">position</span>) </span>{
  <span class="hljs-built_in">console</span>.log(position);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">error</span>(<span class="hljs-params">error</span>) </span>{
  <span class="hljs-built_in">console</span>.log(error);
}

<span class="hljs-comment">// Run the getCurrentPosition() method with custom options</span>
navigator.geolocation.getCurrentPosition(
  success,
  error,
  options
);
</code></pre>
<p>In the code above, the <code>getCurrentPosition()</code> method will use high accuracy mode, and it will wait for 5 minutes for a response from the device.</p>
<h2 id="heading-summary">Summary</h2>
<p>The Geolocation API is a standard JavaScript API that allows a web application to access user location data.</p>
<p>Using the Geolocation data, you can provide services or content relevant to the user's location, such as the nearest public transport or hospital.</p>
<p>If you enjoyed this article and want to learn more from me, I recommend you check out my new book <em><a target="_blank" href="https://codewithnathan.com/beginning-modern-javascript">Beginning Modern JavaScript</a></em>.</p>
<p><a target="_blank" href="https://codewithnathan.com/beginning-modern-javascript"><img src="https://www.freecodecamp.org/news/content/images/2024/01/beginning-js-cover.png" alt="Beginning Modern JavaScript" width="600" height="400" loading="lazy"></a></p>
<p>The book is designed to be easy for beginners and accessible to anyone looking to learn JavaScript. It provides a step-by-step gentle guide to help you understand how to use JavaScript to create a dynamic web application.</p>
<p>Here's my promise: <em>You will actually feel like you understand what you're doing with JavaScript.</em></p>
<p>See you in other articles!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up Geolocation Search in Your App with Elasticsearch ]]>
                </title>
                <description>
                    <![CDATA[ By Pramono Winata Location-based features are pretty common in apps nowadays. These features might seem complicated, but they can actually be implemented quite easily with Elasticsearch. Elasticsearch is a NoSQL database with a document-based structu... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/geolocation-search-elasticsearch/</link>
                <guid isPermaLink="false">66d4608b47a8245f78752a9d</guid>
                
                    <category>
                        <![CDATA[ database ]]>
                    </category>
                
                    <category>
                        <![CDATA[ elasticsearch ]]>
                    </category>
                
                    <category>
                        <![CDATA[ geolocation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ search ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 07 Jan 2021 17:12:37 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5fd644e7e6787e098393e278.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Pramono Winata</p>
<p>Location-based features are pretty common in apps nowadays. These features might seem complicated, but they can actually be implemented quite easily with Elasticsearch.</p>
<p>Elasticsearch is a NoSQL database with a document-based structure. It's often used as a Search Engine. It also provides its own syntax and many tools to help your search be as flexible as possible.</p>
<p>In this article I will show you a simple way to search by geolocation by getting a list of cities by coordinate range.</p>
<h2 id="heading-how-to-install-elasticsearch">How to Install Elasticsearch</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/1-4thJErMA9UpuP1jEBLRWFQ.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can find an easy-to-follow <a target="_blank" href="https://www.elastic.co/guide/en/elasticsearch/reference/7.4/install-elasticsearch.html">installation guide</a> on Elasticsearch's website. At the time I am writing this article, I am using Elasticsearch version 7.4.2 .</p>
<p>Just keep in mind that Elasticsearch has made a lot of changes in recent versions, one of them being the <a target="_blank" href="https://www.elastic.co/guide/en/elasticsearch/reference/master/removal-of-types.html">removal of mapping types.</a> So if you are using another version of Elasticsearch some things here might not fully work.</p>
<p>After finishing your installation, do not forget to run your Elasticsearch service, which they emphasize clearly in their installation guide (for Linux, do this <code>./bin/elasticsearch</code> ).</p>
<p><strong>Make sure your elasticsearch is running</strong> by using a GET request into port 9200 in your local machine, like this: <a target="_blank" href="http://localhost:9200"><code>GET http://localhost:9200</code></a></p>
<h2 id="heading-how-to-make-your-elasticsearch-index">How to Make Your Elasticsearch Index</h2>
<p>An index is similar to table in a regular database. For this example, let's make an index named <code>cities</code> that will contain our data.</p>
<p>Let's also define a simple model for our data: </p>
<ul>
<li><code>id</code> : <code>keyword</code> for our identifier</li>
<li><code>name</code> : <code>text</code> for the city name</li>
<li><code>coordinate</code> : <code>geo_point</code> to store our city coordinates (neat, they have this data-type already)</li>
</ul>
<p>In Elasticsearch, we create the index by making a curl into an API. In our case our request will be like this:</p>
<pre><code>PUT http:<span class="hljs-comment">//localhost:9200/cities</span>
</code></pre><pre><code class="lang-json">{
    <span class="hljs-attr">"settings"</span>: {
        <span class="hljs-attr">"number_of_shards"</span>: <span class="hljs-number">1</span>,
        <span class="hljs-attr">"number_of_replicas"</span>: <span class="hljs-number">1</span>
    },
    <span class="hljs-attr">"mappings"</span>: {
        <span class="hljs-attr">"properties"</span>: {
            <span class="hljs-attr">"id"</span>: {
                <span class="hljs-attr">"type"</span>: <span class="hljs-string">"keyword"</span>
            },
            <span class="hljs-attr">"name"</span>: {
                <span class="hljs-attr">"type"</span>: <span class="hljs-string">"text"</span>
            },
            <span class="hljs-attr">"coordinate"</span>: {
                <span class="hljs-attr">"type"</span>: <span class="hljs-string">"geo_point"</span>
            }
        }
    }
}
</code></pre>
<p>When you used that curl, you should get a response like this to verify that your index has been created:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"acknowledged"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"shards_acknowledged"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"index"</span>: <span class="hljs-string">"cities"</span>
}
</code></pre>
<p>Nicely done! Now your index is ready to be used. Let's go ahead and play around with our newly created index.</p>
<h2 id="heading-how-to-populate-elasticsearch-data">How to Populate Elasticsearch Data</h2>
<p>We will now fill our Elasticsearch index with documents. If you are not familiar with this term, just know that it is very similar to rows in a SQL database.</p>
<p>In Elasticsearch, it's possible to store data that doesn't match with our predefined schema. But we will not do that here – instead we will insert data that matches our predefined schema.</p>
<p>Since we will be inserting multiple data at once, we will use the <a target="_blank" href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html">bulk</a> API that Elasticsearch provides that allows multiple insertions in one API call.</p>
<p>In the example below, I will be inserting 9 cities into my index. Feel free to add more if you wish.</p>
<p><code>POST '[http://localhost:9200/cities/_bu](http://localhost:9200/cities/_bu)lk</code></p>
<pre><code class="lang-json">{ <span class="hljs-attr">"index"</span>:{<span class="hljs-attr">"_index"</span>: <span class="hljs-string">"cities"</span> } }
{ <span class="hljs-attr">"id"</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Jakarta"</span>, <span class="hljs-attr">"coordinate"</span>: {  <span class="hljs-attr">"lat"</span>: <span class="hljs-number">-6.2008</span>, <span class="hljs-attr">"lon"</span>: <span class="hljs-number">106.8456</span>}}
{ <span class="hljs-attr">"index"</span>:{<span class="hljs-attr">"_index"</span>: <span class="hljs-string">"cities"</span> } }
{ <span class="hljs-attr">"id"</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Tokyo"</span>, <span class="hljs-attr">"coordinate"</span>: {  <span class="hljs-attr">"lat"</span>: <span class="hljs-number">35.6762</span>, <span class="hljs-attr">"lon"</span>: <span class="hljs-number">139.6503</span>} }
{ <span class="hljs-attr">"index"</span>:{<span class="hljs-attr">"_index"</span>: <span class="hljs-string">"cities"</span> } }
{ <span class="hljs-attr">"id"</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Hong Kong"</span>, <span class="hljs-attr">"coordinate"</span>: {  <span class="hljs-attr">"lat"</span>: <span class="hljs-number">22.3193</span>, <span class="hljs-attr">"lon"</span>: <span class="hljs-number">114.1694</span>} }
{ <span class="hljs-attr">"index"</span>:{<span class="hljs-attr">"_index"</span>: <span class="hljs-string">"cities"</span> } }
{ <span class="hljs-attr">"id"</span>: <span class="hljs-number">4</span>, <span class="hljs-attr">"name"</span>: <span class="hljs-string">"New York"</span>, <span class="hljs-attr">"coordinate"</span>: {  <span class="hljs-attr">"lat"</span>: <span class="hljs-number">40.7128</span>, <span class="hljs-attr">"lon"</span>: <span class="hljs-number">-74.0060</span>} }
{ <span class="hljs-attr">"index"</span>:{<span class="hljs-attr">"_index"</span>: <span class="hljs-string">"cities"</span> } }
{ <span class="hljs-attr">"id"</span>: <span class="hljs-number">5</span>, <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Paris"</span>, <span class="hljs-attr">"coordinate"</span>: {  <span class="hljs-attr">"lat"</span>: <span class="hljs-number">48.8566</span>, <span class="hljs-attr">"lon"</span>: <span class="hljs-number">2.3522</span>} }
{ <span class="hljs-attr">"index"</span>:{<span class="hljs-attr">"_index"</span>: <span class="hljs-string">"cities"</span> } }
{ <span class="hljs-attr">"id"</span>: <span class="hljs-number">6</span>, <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Bali"</span>, <span class="hljs-attr">"coordinate"</span>: {  <span class="hljs-attr">"lat"</span>: <span class="hljs-number">-8.3405</span>, <span class="hljs-attr">"lon"</span>: <span class="hljs-number">115.0920</span>} }
{ <span class="hljs-attr">"index"</span>:{<span class="hljs-attr">"_index"</span>: <span class="hljs-string">"cities"</span> } }
{ <span class="hljs-attr">"id"</span>: <span class="hljs-number">7</span>, <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Berlin"</span>, <span class="hljs-attr">"coordinate"</span>: {  <span class="hljs-attr">"lat"</span>: <span class="hljs-number">52.5200</span>, <span class="hljs-attr">"lon"</span>: <span class="hljs-number">13.4050</span>} }
{ <span class="hljs-attr">"index"</span>:{<span class="hljs-attr">"_index"</span>: <span class="hljs-string">"cities"</span> } }
{ <span class="hljs-attr">"id"</span>: <span class="hljs-number">8</span>, <span class="hljs-attr">"name"</span>: <span class="hljs-string">"San Fransisco"</span>, <span class="hljs-attr">"coordinate"</span>: {  <span class="hljs-attr">"lat"</span>: <span class="hljs-number">37.7749</span>, <span class="hljs-attr">"lon"</span>: <span class="hljs-number">-122.4194</span>} }
{ <span class="hljs-attr">"index"</span>:{<span class="hljs-attr">"_index"</span>: <span class="hljs-string">"cities"</span> } }
{ <span class="hljs-attr">"id"</span>: <span class="hljs-number">9</span>, <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Beijing"</span>, <span class="hljs-attr">"coordinate"</span>: {  <span class="hljs-attr">"lat"</span>: <span class="hljs-number">39.9042</span>, <span class="hljs-attr">"lon"</span>: <span class="hljs-number">166.4074</span>} }
</code></pre>
<p>The payload might looks weird since it's in an incorrect JSON format, but don't worry – it's supposedly designed that way.</p>
<p>It should then reply back to you with a response similar to this:</p>
<pre><code>{
    <span class="hljs-string">"took"</span>: <span class="hljs-number">72</span>,
    <span class="hljs-string">"errors"</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-string">"items"</span>: [
        <span class="hljs-comment">//will contains item for each data inserted</span>
        ...
    ]
}
</code></pre><h2 id="heading-how-to-query-your-elasticsearch-documents">How to Query Your Elasticsearch Documents</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-276.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@chrislawton?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Chris Lawton / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>Now comes the interesting part. We are going to do some querying with the documents that we inserted before.</p>
<p>Elasticsearch supports many types of syntax for query searching. It also has geolocation type searching which we will play around with today.</p>
<p>We can simply start searching for our cities with curl like this:</p>
<p><code>POST '[http://localhost:9200/cities/_sear](http://localhost:9200/cities/_sear)ch</code></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"query"</span>: {
    <span class="hljs-attr">"bool"</span>: {
      <span class="hljs-attr">"filter"</span>: {
        <span class="hljs-attr">"geo_distance"</span>: {
          <span class="hljs-attr">"distance"</span>: <span class="hljs-string">"10km"</span>,
          <span class="hljs-attr">"coordinate"</span>: {
            <span class="hljs-attr">"lat"</span>: <span class="hljs-number">37.76</span>,
            <span class="hljs-attr">"lon"</span>: <span class="hljs-number">-122.42</span>
          }
        }
      }
    }
  }
}
</code></pre>
<p>That query should give me San Francisco, and the coordinates 37.7749 and -122.4194 should be inside a 10km distance radius from our coordinates (courtesy of Google).</p>
<pre><code>{
    <span class="hljs-string">"took"</span>: <span class="hljs-number">7</span>,
    <span class="hljs-string">"timed_out"</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-string">"_shards"</span>: {
        <span class="hljs-string">"total"</span>: <span class="hljs-number">1</span>,
        <span class="hljs-string">"successful"</span>: <span class="hljs-number">1</span>,
        <span class="hljs-string">"skipped"</span>: <span class="hljs-number">0</span>,
        <span class="hljs-string">"failed"</span>: <span class="hljs-number">0</span>
    },
    <span class="hljs-string">"hits"</span>: {
        <span class="hljs-string">"total"</span>: {
            <span class="hljs-string">"value"</span>: <span class="hljs-number">1</span>,
            <span class="hljs-string">"relation"</span>: <span class="hljs-string">"eq"</span>
        },
        <span class="hljs-string">"max_score"</span>: <span class="hljs-number">0.0</span>,
        <span class="hljs-string">"hits"</span>: [
            {
                <span class="hljs-string">"_index"</span>: <span class="hljs-string">"cities"</span>,
                <span class="hljs-string">"_type"</span>: <span class="hljs-string">"_doc"</span>,
                <span class="hljs-string">"_id"</span>: <span class="hljs-string">"eKPspHYBivyIhfWHb2vl"</span>,
                <span class="hljs-string">"_score"</span>: <span class="hljs-number">0.0</span>,
                <span class="hljs-string">"_source"</span>: {
                    <span class="hljs-string">"id"</span>: <span class="hljs-number">8</span>,
                    <span class="hljs-string">"name"</span>: <span class="hljs-string">"San Fransisco"</span>,
                    <span class="hljs-string">"coordinate"</span>: {
                        <span class="hljs-string">"lat"</span>: <span class="hljs-number">37.7749</span>,
                        <span class="hljs-string">"lon"</span>: <span class="hljs-number">-122.4194</span>
                    }
                }
            }
        ]
    }
}
</code></pre><p>Congratulations! Now you have your own location search engine.<br>But let's experiment a bit more. Let's say you want to get more cities in that location.</p>
<p>Let's try to expand the distance to 4500km by changing the payload:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"query"</span>: {
    <span class="hljs-attr">"bool"</span>: {
      <span class="hljs-attr">"filter"</span>: {
        <span class="hljs-attr">"geo_distance"</span>: {
          <span class="hljs-attr">"distance"</span>: <span class="hljs-string">"4500km"</span>,
          <span class="hljs-attr">"coordinate"</span>: {
            <span class="hljs-attr">"lat"</span>: <span class="hljs-number">37.76</span>,
            <span class="hljs-attr">"lon"</span>: <span class="hljs-number">-122.42</span>
          }
        }
      }
    }
  }
}
</code></pre>
<p>And you should get this response:</p>
<pre><code>{
    <span class="hljs-string">"took"</span>: <span class="hljs-number">8</span>,
    <span class="hljs-string">"timed_out"</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-string">"_shards"</span>: {
        <span class="hljs-string">"total"</span>: <span class="hljs-number">1</span>,
        <span class="hljs-string">"successful"</span>: <span class="hljs-number">1</span>,
        <span class="hljs-string">"skipped"</span>: <span class="hljs-number">0</span>,
        <span class="hljs-string">"failed"</span>: <span class="hljs-number">0</span>
    },
    <span class="hljs-string">"hits"</span>: {
        <span class="hljs-string">"total"</span>: {
            <span class="hljs-string">"value"</span>: <span class="hljs-number">2</span>,
            <span class="hljs-string">"relation"</span>: <span class="hljs-string">"eq"</span>
        },
        <span class="hljs-string">"max_score"</span>: <span class="hljs-number">0.0</span>,
        <span class="hljs-string">"hits"</span>: [
            {
                <span class="hljs-string">"_index"</span>: <span class="hljs-string">"cities"</span>,
                <span class="hljs-string">"_type"</span>: <span class="hljs-string">"_doc"</span>,
                <span class="hljs-string">"_id"</span>: <span class="hljs-string">"dKPspHYBivyIhfWHb2vl"</span>,
                <span class="hljs-string">"_score"</span>: <span class="hljs-number">0.0</span>,
                <span class="hljs-string">"_source"</span>: {
                    <span class="hljs-string">"id"</span>: <span class="hljs-number">4</span>,
                    <span class="hljs-string">"name"</span>: <span class="hljs-string">"New York"</span>,
                    <span class="hljs-string">"coordinate"</span>: {
                        <span class="hljs-string">"lat"</span>: <span class="hljs-number">40.7128</span>,
                        <span class="hljs-string">"lon"</span>: <span class="hljs-number">-74.0060</span>
                    }
                }
            },
            {
                <span class="hljs-string">"_index"</span>: <span class="hljs-string">"cities"</span>,
                <span class="hljs-string">"_type"</span>: <span class="hljs-string">"_doc"</span>,
                <span class="hljs-string">"_id"</span>: <span class="hljs-string">"eKPspHYBivyIhfWHb2vl"</span>,
                <span class="hljs-string">"_score"</span>: <span class="hljs-number">0.0</span>,
                <span class="hljs-string">"_source"</span>: {
                    <span class="hljs-string">"id"</span>: <span class="hljs-number">8</span>,
                    <span class="hljs-string">"name"</span>: <span class="hljs-string">"San Fransisco"</span>,
                    <span class="hljs-string">"coordinate"</span>: {
                        <span class="hljs-string">"lat"</span>: <span class="hljs-number">37.7749</span>,
                        <span class="hljs-string">"lon"</span>: <span class="hljs-number">-122.4194</span>
                    }
                }
            }
        ]
    }
}
</code></pre><p>It gives two results: New York and San Fransisco. The results look correct, but the positioning might be a bit weird. San Fransisco supposedly should come first since it's closer, right?</p>
<p>Well not exactly, since what we are doing is just filtering. Our query is just filtering and it doesn't care about which one is closest to you. </p>
<p>But what if we want to do some calculation to show which locations might be the nearest? Don't worry, Elasticsearch can do that too. We can use a type of query called a function score query.</p>
<h3 id="heading-how-to-use-a-function-score-query-in-elasticsearch">How to Use a Function Score Query in Elasticsearch</h3>
<p>Elasticsearch calculates (scores) what documents it will show to the user. By using <a target="_blank" href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html">function score queries</a> we can modify that score so we can determine which documents should be returned.</p>
<p>Here, we will be using the <a target="_blank" href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-decay">decay query function</a>. There are three kinds of decay functions: exp, linear, and gauss. Each of them has different behaviors.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/decay_2d.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image <a target="_blank" href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-decay">source</a></em></p>
<p>The one we will use here is the linear type function. We will also specify the coordinates together with offset and scale.</p>
<p><code>POST '[http://localhost:9200/cities/_sear](http://localhost:9200/cities/_sear)ch</code></p>
<pre><code>{
  <span class="hljs-string">"query"</span>: {
    <span class="hljs-string">"function_score"</span>: {
      <span class="hljs-string">"functions"</span>: [
        {
          <span class="hljs-string">"linear"</span>: {
            <span class="hljs-string">"coordinate"</span>: {
              <span class="hljs-string">"origin"</span>: <span class="hljs-string">"37, -122"</span>,
              <span class="hljs-string">"offset"</span>: <span class="hljs-string">"100km"</span>,
              <span class="hljs-string">"scale"</span>:<span class="hljs-string">"2500km"</span>
            }
          }
        }
      ],
       <span class="hljs-string">"min_score"</span>:<span class="hljs-string">"0.1"</span>
    }
  }
}
</code></pre><p>Now, we should get our results ordered by the highest score.</p>
<pre><code>{
    <span class="hljs-string">"took"</span>: <span class="hljs-number">32</span>,
    <span class="hljs-string">"timed_out"</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-string">"_shards"</span>: {
        <span class="hljs-string">"total"</span>: <span class="hljs-number">1</span>,
        <span class="hljs-string">"successful"</span>: <span class="hljs-number">1</span>,
        <span class="hljs-string">"skipped"</span>: <span class="hljs-number">0</span>,
        <span class="hljs-string">"failed"</span>: <span class="hljs-number">0</span>
    },
    <span class="hljs-string">"hits"</span>: {
        <span class="hljs-string">"total"</span>: {
            <span class="hljs-string">"value"</span>: <span class="hljs-number">2</span>,
            <span class="hljs-string">"relation"</span>: <span class="hljs-string">"eq"</span>
        },
        <span class="hljs-string">"max_score"</span>: <span class="hljs-number">1.0</span>,
        <span class="hljs-string">"hits"</span>: [
            {
                <span class="hljs-string">"_index"</span>: <span class="hljs-string">"cities"</span>,
                <span class="hljs-string">"_type"</span>: <span class="hljs-string">"_doc"</span>,
                <span class="hljs-string">"_id"</span>: <span class="hljs-string">"eKPspHYBivyIhfWHb2vl"</span>,
                <span class="hljs-string">"_score"</span>: <span class="hljs-number">1.0</span>,
                <span class="hljs-string">"_source"</span>: {
                    <span class="hljs-string">"id"</span>: <span class="hljs-number">8</span>,
                    <span class="hljs-string">"name"</span>: <span class="hljs-string">"San Fransisco"</span>,
                    <span class="hljs-string">"coordinate"</span>: {
                        <span class="hljs-string">"lat"</span>: <span class="hljs-number">37.7749</span>,
                        <span class="hljs-string">"lon"</span>: <span class="hljs-number">-122.4194</span>
                    }
                }
            },
            {
                <span class="hljs-string">"_index"</span>: <span class="hljs-string">"cities"</span>,
                <span class="hljs-string">"_type"</span>: <span class="hljs-string">"_doc"</span>,
                <span class="hljs-string">"_id"</span>: <span class="hljs-string">"dKPspHYBivyIhfWHb2vl"</span>,
                <span class="hljs-string">"_score"</span>: <span class="hljs-number">0.19508117</span>,
                <span class="hljs-string">"_source"</span>: {
                    <span class="hljs-string">"id"</span>: <span class="hljs-number">4</span>,
                    <span class="hljs-string">"name"</span>: <span class="hljs-string">"New York"</span>,
                    <span class="hljs-string">"coordinate"</span>: {
                        <span class="hljs-string">"lat"</span>: <span class="hljs-number">40.7128</span>,
                        <span class="hljs-string">"lon"</span>: <span class="hljs-number">-74.0060</span>
                    }
                }
            }
        ]
    }
}
</code></pre><p>And that wraps it up!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, we've covered how to implement location-based search with Elasticsearch. But this is not the end – what I have shown here is just the surface of what you can do. </p>
<p>I hope you found this article interesting and useful. If so, keep learning more about it and try to experiment with combining function scoring. It will be fun, I promise.</p>
<blockquote>
<p>Always be curios and you will learn something new.</p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
