Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Add Location-based Searching to Your PHP App with Elasticsearch

derek-b
February 08, 2020

Add Location-based Searching to Your PHP App with Elasticsearch

Searching based on a user's location is a feature of many websites and applications. This type of search can add relevancy and value to a website, especially when these results can include distance from a point, within a rectangle or other shape, combined with fast text searches. In this talk we'll take an in depth look at how Elasticsearch supports geosearching. We'll look at the different types of location searches and how to integrate them into your PHP application. By the end of this talk you will be able to add awesomely relevant location based searches that will impress your users.

derek-b

February 08, 2020
Tweet

More Decks by derek-b

Other Decks in Technology

Transcript

  1. @DerekB_WI BELK Stack • Beats - Ingests data streams •

    Elasticsearch - You know for search • Logstash - Prebuilt dashboard for visualizing logs • Kibana - Browser based client
  2. @DerekB_WI docker-compose.yml version: '3'
 services:
 elasticsearch:
 image: docker.elastic.co/elasticsearch/elasticsearch:6.3.2
 environment:
 -

    cluster.name=docker-cluster
 - bootstrap.memory_lock=true
 - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
 ulimits:
 memlock:
 soft: -1
 hard: -1
 ports:
 - "9200:9200"
 kibana:
 image: docker.elastic.co/kibana/kibana:6.3.2
 ports:
 - "5601:5601"
  3. @DerekB_WI How is it stored? • Document - A JSON

    document for each data element • Index - A grouping of documents with similar structure • Mapping - Defines what is contained in document
  4. @DerekB_WI Data Types • Text - Content is indexed and

    searchable • Keyword - Fixed content, think lookup table • Geo-point - latitude/longitude • Geo-shape - Define a polygon • long, integer, short, byte, double, float, half_float, scaled_floa t, date, date_nanos, boolean, binary • More at https://www.elastic.co/guide/en/elasticsearch/ reference/current/mapping-types.html
  5. @DerekB_WI Queries GET location-list/location/_search
 {
 "query": {
 "bool": {
 "filter":

    {
 "term": {"feature_class": "L"}
 }
 }
 }
 } https://www.geonames.org/export/codes.html
  6. @DerekB_WI Queries GET location-list/location/_search
 {
 "query": {
 "bool": {
 "must":{


    "match": {"name":"Little Park"}
 },
 "filter": {
 "term": {"feature_class": "L"}
 }
 }
 }
 }
  7. @DerekB_WI Benefits? • Fast - 2.4 mil rows in 15ms

    • Search within text • Other search types, geo, more like this
  8. @DerekB_WI Load Data public function addLocation(Location $location)
 {
 $this->locations[] =

    $location;
 
 if (count($this->locations) >= 1000)
 {
 $this->repository
 ->bulkInsert('location-list', 'location', 
 $this->prepareBulkJson($this->locations)); $this->locations = [];
 } }
  9. @DerekB_WI Load Data private function prepareBulkJson()
 {
 return array_map(function($location) {


    return [
 'geonameid' => $location->geonameid,
 'name' => $location->name,
 'asciiname' => $location->asciiname,
 'alternatenames' => $location->alternatenames,
 'location_point' => $location->latitude . ", " $location->longitude,
 'feature_class' => $location->featureClass,
 'feature_code' => $location->featureCode,
 'elevation' => $location->elevation,
 'timezone' => $location->timezone
 ];
 }, $this->locations);

  10. @DerekB_WI Load Data public function bulkInsert($indexName, $indexType, $data_lines) { $client

    = ClientBuilder::create() ->setHosts(['127.0.0.1:9200']) ->build(); $json_body = []; foreach ($data_lines as $line) { $json_body[] = ['index' => [ '_index' => $indexName, '_type' => $indexType ] ]; $json_body[] = $line; } $responses = $client->bulk(['body' => $json_body]); }
  11. @DerekB_WI Load Data public function bulkInsert($indexName, $indexType, $data_lines) { $client

    = ClientBuilder::create() ->setHosts(['127.0.0.1:9200']) ->build(); $json_body = []; foreach ($data_lines as $line) { $json_body[] = ['index' => ['_index' => $indexName, '_type' => $indexType] ]; $json_body[] = $line; } $responses = $client->bulk(['body' => $json_body]); }
  12. @DerekB_WI Load Data public function bulkInsert($indexName, $indexType, $data_lines) { $client

    = ClientBuilder::create() ->setHosts(['127.0.0.1:9200']) ->build(); $json_body = []; foreach ($data_lines as $line) { $json_body[] = ['index' => ['_index' => $indexName, '_type' => $indexType] ]; $json_body[] = $line; } $responses = $client->bulk(['body' => $json_body]); }