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

Getting things done with Elasticsearch - Devtalks 2015

Getting things done with Elasticsearch - Devtalks 2015

Slides for my Elasticsearch talk at Devtalks 2015 in Cluj Romania

Thijs Feryn

May 13, 2015
Tweet

More Decks by Thijs Feryn

Other Decks in Technology

Transcript

  1. Getting things done with
    Elasticsearch
    By Thijs Feryn

    View Slide

  2. Explain in 1 slide

    View Slide

  3. •Full-text search database
    •NoSQL database
    •Analytics engine
    •Written in Java
    •Lucene based ( ~Solr)
    •Inverted indices
    •Easy to scale (~Elastic)
    •RESTFul interface (HTTP/JSON)
    •Schemaless
    •Real-time
    •ELK stack

    View Slide

  4. Still with me?

    View Slide

  5. Hi, I’m Thijs

    View Slide

  6. I’m
    @ThijsFeryn
    on Twitter

    View Slide

  7. I’m an
    at
    Evangelist

    View Slide

  8. I’m a
    at
    board member

    View Slide

  9. https://www.elastic.co/
    downloads/elasticsearch

    View Slide

  10. {  
       "status"  :  200,  
       "name"  :  "War  V",  
       "cluster_name"  :  "elasticsearch",  
       "version"  :  {  
           "number"  :  "1.5.2",  
           "build_hash"  :  
    "62ff9868b4c8a0c45860bebb259e21980778ab1c",  
           "build_timestamp"  :  "2015-­‐04-­‐27T09:21:06Z",  
           "build_snapshot"  :  false,  
           "lucene_version"  :  "4.10.4"  
       },  
       "tagline"  :  "You  Know,  for  Search"  
    }
    http://localhost:9200

    View Slide

  11. RDBMS Elasticsearch
    Database
    Table
    Row
    Index
    Type
    Document

    View Slide

  12. POST  /my-­‐index  
    {"acknowledged":true}  
    POST/my-­‐index/my-­‐type  
    {  
       "key"  :  "value",  
       "date"  :  "2015-­‐05-­‐10",  
       "counter"  :  1,  
       "tags"  :  ["tag1","tag2","tag3"]  
    }  
    {  
         "_index":  "my-­‐index",  
         "_type":  "my-­‐type",  
         "_id":  "AU089olr9oI99a_rK9fi",  
         "_version":  1,  
         "created":  true  
    }
    CREATE  DATABASE  my-­‐index
    INSERT  INTO  my-­‐index.my-­‐type  (key,date,counter,tags)    
    VALUES  ("value","2015-­‐05-­‐10",1,"tag1,tag2,tag3")
    Confirmation

    View Slide

  13. GET/my-­‐index/my-­‐type/AU089olr9oI99a_rK9fi?pretty  
    {  
         "_index":  "my-­‐index",  
         "_type":  "my-­‐type",  
         "_id":  "AU089olr9oI99a_rK9fi",  
         "_version":  1,  
         "found":  true,  
         "_source":  {  
               "key":  "value",  
               "date":  "2015-­‐05-­‐10",  
               "counter":  1,  
               "tags":  [  
                     "tag1",  
                     "tag2",  
                     "tag3"  
               ]  
         }  
    }
    Retrieve
    document by
    id
    Document &
    meta data
    SELECT  *    
    FROM  my-­‐index.my-­‐type  
    WHERE  
    id="AU089olr9oI99a_rK9fi"

    View Slide

  14. GET  /my-­‐index/_mapping?pretty  
    {  
         "my-­‐index":  {  
               "mappings":  {  
                     "my-­‐type":  {  
                           "properties":  {  
                                 "counter":  {  
                                       "type":  "long"  
                                 },  
                                 "date":  {  
                                       "type":  "date",  
                                       "format":  "dateOptionalTime"  
                                 },  
                                 "key":  {  
                                       "type":  "string"  
                                 },  
                                 "tags":  {  
                                       "type":  "string"  
                                 }  
                           }  
                     }  
               }  
         }  
    }
    Schemaless?
    Not really …
    “Guesses”
    mapping on
    insert

    View Slide

  15. Explicit mapping
    … using actual data

    View Slide

  16. mysql>  desc  catalog_product_flat_1;  
    +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐-­‐-­‐+  
    |  Field                                                    |  Type                                  |  Null  |  Key  |  Default  |  Extra  |  
    +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐-­‐-­‐+  
    |  entity_id                                            |  int(10)  unsigned          |  NO      |  PRI  |  NULL        |              |  
    |  attribute_set_id                              |  smallint(5)  unsigned  |  NO      |  MUL  |  0              |              |  
    |  type_id                                                |  varchar(32)                    |  NO      |  MUL  |  simple    |              |  
    |  allow_open_amount                            |  int(11)                            |  YES    |          |  NULL        |              |  
    |  cost                                                      |  decimal(12,4)                |  YES    |          |  NULL        |              |  
    |  created_at                                          |  timestamp                        |  YES    |          |  NULL        |              |  
    |  email_template                                  |  varchar(255)                  |  YES    |          |  NULL        |              |  
    |  enable_googlecheckout                    |  smallint(6)                    |  YES    |          |  NULL        |              |  
    |  giftcard_amounts                              |  decimal(12,4)                |  YES    |          |  NULL        |              |  
    |  giftcard_type                                    |  smallint(5)  unsigned  |  YES    |          |  NULL        |              |  
    |  gift_message_available                  |  smallint(6)                    |  YES    |          |  NULL        |              |  
    |  gift_wrapping_available                |  smallint(6)                    |  YES    |          |  NULL        |              |  
    |  gift_wrapping_price                        |  decimal(12,4)                |  YES    |          |  NULL        |              |  
    |  has_options                                        |  smallint(6)                    |  NO      |          |  0              |              |  
    |  image_label                                        |  varchar(255)                  |  YES    |          |  NULL        |              |  
    |  is_recurring                                      |  smallint(6)                    |  YES    |          |  NULL        |              |  
    |  is_redeemable                                    |  int(11)                            |  YES    |          |  NULL        |              |  
    |  lifetime                                              |  int(11)                            |  YES    |          |  NULL        |              |  
    |  links_exist                                        |  int(11)                            |  YES    |          |  NULL        |              |  
    |  links_purchased_separately          |  int(11)                            |  YES    |          |  NULL        |              |  
    |  links_title                                        |  varchar(255)                  |  YES    |          |  NULL        |              |  
    |  msrp                                                      |  decimal(12,4)                |  YES    |          |  NULL        |              |  
    |  msrp_display_actual_price_type  |  varchar(255)                  |  YES    |          |  NULL        |              |  
    |  msrp_enabled                                      |  smallint(6)                    |  YES    |          |  NULL        |              |  
    |  name                                                      |  varchar(255)                  |  YES    |  MUL  |  NULL        |              |  
    |  news_from_date                                  |  datetime                          |  YES    |          |  NULL        |              |  
    |  news_to_date                                      |  datetime                          |  YES    |          |  NULL        |              |  
    |  open_amount_max                                |  decimal(12,4)                |  YES    |          |  NULL        |              |  
    |  open_amount_min                                |  decimal(12,4)                |  YES    |          |  NULL        |              |  
    |  price                                                    |  decimal(12,4)                |  YES    |  MUL  |  NULL        |              |  
    |  price_type                                          |  int(11)                            |  YES    |          |  NULL        |              |  
    |  price_view                                          |  int(11)                            |  YES    |          |  NULL        |              |  
    |  recurring_profile                            |  text                                  |  YES    |          |  NULL        |              |  
    |  required_options                              |  smallint(5)  unsigned  |  NO      |          |  0              |              |  
    |  shipment_type                                    |  int(11)                            |  YES    |          |  NULL        |              |  
    |  short_description                            |  text                                  |  YES    |          |  NULL        |              |  
    |  sku                                                        |  varchar(64)                    |  YES    |          |  NULL        |              |  
    |  sku_type                                              |  int(11)                            |  YES    |          |  NULL        |              |  
    |  small_image                                        |  varchar(255)                  |  YES    |          |  NULL        |              |  
    |  small_image_label                            |  varchar(255)                  |  YES    |          |  NULL        |              |  
    Magento’s
    flattened product
    table

    View Slide

  17. Import data
    from MySQL to
    ElasticSearch

    View Slide

  18. {  
           "category":  [  
                   "Default  Category",  
                   "Men",  
                   "Shirts"  
           ],  
           "entity_id":  "231",  
           "created_at":  "2013-­‐03-­‐05  06:48:12",  
           "updated_at":  "2013-­‐03-­‐05  09:27:15",  
           "name":  "French  Cuff  Cotton  Twill  Oxford",  
           "price":  "190.0000",  
           "description":  "Made  with  wrinkle  resistant  cotton  twill,  this  French-­‐cuffed  
    luxury  dress  shirt  is  perfect  for  Business  Class  frequent  flyers.",  
           "sku":  "msj000"  
    }
    SELECT  GROUP_CONCAT(distinct  c.name)  as  category,p.entity_id,  p.created_at,  
    p.updated_at,  p.name,  p.price,  p.short_description  as  description,p.sku    
    FROM  catalog_product_flat_1    p  
    JOIN  `catalog_category_product_index`  AS  `cat_index`  ON  
    cat_index.product_id=p.entity_id  
    JOIN  `catalog_category_flat_store_1`  AS  `c`  ON  
    cat_index.category_id=c.entity_id  
    WHERE  cat_index.store_id  =  1  AND  cat_index.visibility=1  
    GROUP  BY  p.name  
    ORDER  BY  p.entity_id

    View Slide

  19. POST  /products  
    {  
           "mappings":  {  
                   "product"  :  {  
                           "_id"  :  {  
                                   "path"  :  "entity_id"  
                           },  
                           "properties"  :  {  
                                   "entity_id"  :  {"type"  :  "integer"},  
                                   "name"  :  {  
                                           "type"  :  "string",    
                                           "index"  :  "not_analyzed",  
                                           "fields"  :  {  
                                                   "raw"  :  {  
                                                           "type"  :  "string",  
                                                           "analyzer":  "english"  
                                                   }  
                                           }  
                                   },  
                                   "description"  :  {  
                                           "type"  :  "string",    
                                           "index"  :  "not_analyzed",  
                                           "fields"  :  {  
                                                   "raw"  :  {  
                                                           "type"  :  "string",  
                                                           "analyzer":  "english"  
                                                   }  
                                           }  
                                   },  
                                   "price"  :  {"type"  :  "double"},  
                                   "sku"  :  {"type"  :  "string",  "index"  :  "not_analyzed"},  
                                   "created_at"  :  {"type"  :  "date",  "format"  :  "YYYY-­‐MM-­‐dd  HH:mm:ss"},  
                                   "updated_at"  :  {"type"  :  "date",  "format"  :  "YYYY-­‐MM-­‐dd  HH:mm:ss"}  ,  
                                   "category"  :  {  
                                           "type"  :  "string",  
                                           "index"  :  "not_analyzed"  
                                   }                                
                           }  
                   }  
           }  
    }
    Explicit
    mapping at
    index creation
    time

    View Slide

  20.      "entity_id"  :  {"type"  :  "integer"},  
         "name"  :  {  
                 "type"  :  "string",    
                 "index"  :  "not_analyzed",  
                 "fields"  :  {  
                         "raw"  :  {  
                                 "type"  :  "string",  
                                 "analyzer":  "english"  
                         }  
                 }  
         },  
         "description"  :  {  
                 "type"  :  "string",    
                 "index"  :  "not_analyzed",  
                 "fields"  :  {  
                         "raw"  :  {  
                                 "type"  :  "string",  
                                 "analyzer":  "english"  
                         }  
                 }  
         },  
         "price"  :  {"type"  :  "double"},  
         "sku"  :  {"type"  :  "string",  "index"  :  "not_analyzed"},  
         "created_at"  :  {"type"  :  "date",  "format"  :  "YYYY-­‐MM-­‐dd  HH:mm:ss"},  
         "updated_at"  :  {"type"  :  "date",  "format"  :  "YYYY-­‐MM-­‐dd  HH:mm:ss"}  ,  
         "category"  :  {  
                 "type"  :  "string",  
                 "index"  :  "not_analyzed"  
         }                                
    Not
    analyzed?
    English
    analyzer?

    View Slide

  21. Analyzed
    vs
    non-analyzed

    View Slide

  22. Full-text
    vs
    exact value

    View Slide

  23. Analyzer
    •Character filters
    •Tokenizers
    •Token filters
    Replaces
    characters
    for analyzed
    text
    Break text
    down into
    terms
    Add/modify/
    delete tokens

    View Slide

  24. Built-in analyzers
    •Standard
    •Simple
    •Whitespace
    •Stop
    •Keyword
    •Pattern
    •Language
    •Snowball
    •Custom
    Standard
    tokenizer
    Lowercase
    token filter
    English
    stop word
    token filter

    View Slide

  25. Set the shape to semi-transparent by calling
    set_trans(5)
    set, the, shape, to, semi, transparent, by, calling,
    set_trans, 5
    set, the, shape, to, semi, transparent, by, calling,
    set, trans
    Set, the, shape, to, semi-transparent, by, calling,
    set_trans(5)
    set, shape, semi, transpar, call, set_tran, 5
    Standard
    Simple
    Whitespace
    English

    View Slide

  26. Building a custom analyzer
    PUT  /my_index  
    {  
       "settings":  {  
           "analysis":  {  
               "char_filter":  {  
                   "&_to_and":  {  
                       "type":  "mapping",  
                       "mappings":  [  "&=>  and  "]  
                   }},  
               "filter":  {  
                   "my_stopwords":  {  
                       "type":  "stop",  
                       "stopwords":  [  "the",  "a"  ]  
                   }},  
                   "analyzer":  {  
                       "my_analyzer":  {  
                           "type":  "custom",  
                           "char_filter":    [  "html_strip",  "&_to_and"  ],  
                           "tokenizer":  "standard",  
                           "filter":  [  "lowercase",  "my_stopwords"  ]  
                           }}  
    }}}

    View Slide

  27. Search

    View Slide

  28. GET  /products/product/_search?pretty  
    {  
         "took":  2,  
         "timed_out":  false,  
         "_shards":  {  
               "total":  1,  
               "successful":  1,  
               "failed":  0  
         },  
         "hits":  {  
               "total":  192,  
               "max_score":  1,  
               "hits":  [  
                     {  
                           "_index":  "products",  
                           "_type":  "product",  
                           "_id":  "231",  
                           "_score":  1,  
                           "_source":  {  
                                 "category":  [  
                                       "Default  Category",  
                                       "Men",  
                                       "Shirts"  
                                 ],  
                                 "entity_id":  "231",  
                                 "created_at":  "2013-­‐03-­‐05  06:48:12",  
                                 "updated_at":  "2013-­‐03-­‐05  09:27:15",  
                                 "name":  "French  Cuff  Cotton  Twill  Oxford",  
                                 "price":  "190.0000",  
                                 "description":  "Made  with  wrinkle  resistant  cotton  
    twill,  this  French-­‐cuffed  luxury  dress  shirt  is  perfect  for  Business  
    Class  frequent  flyers.",  
                                 "sku":  "msj000"  
                           }  
                     },  

    SELECT  *  FROM  
    products.product  

    View Slide

  29. GET  /products/product/_search?pretty  
    POST  /products/product/_search?pretty  
    {  
         
       "query":  {  
           "match_all":  {}  
       }  
    }  
    Search
    “lite” vs full
    query DSL
    SELECT  *  FROM  
    products.product  

    View Slide

  30. GET  /products/product/_search?
    pretty&q=name.raw:Blazer  
    POST  /products/product/_search?pretty  
    {  
       "query":  {  
           "match":  {  
               "name.raw":  "Blazer"  
           }  
       }  
    }   SELECT  *  FROM  
    products.product    
    WHERE    
    name  LIKE  "%Blazer%"
    Search
    “lite” vs full
    query DSL

    View Slide

  31. SELECT  *  FROM  
    products.product    
    WHERE    
    name  =  "Linen  Blazer"
    POST  /products/product/_search?
    pretty  
    {  
       "query":  {  
           "match":  {  
               "name.raw":  "Linen  Blazer"  
           }  
       }  
    }  
    POST  /products/product/_search?
    pretty  
    {  
       "query":  {  
           "filtered":  {  
               "query":  {  
                   "match_all":  {}  
               },  
               "filter":  {  
                   "term":  {  
                       "name":  "Linen  Blazer"  
                   }  
               }  
           }  
       }  
    }
    Matches
    2 products
    Matches 1
    product
    SELECT  *  FROM  
    products.product    
    WHERE    
    name  LIKE  "%Linen%"    
    OR    
    name  LIKE  "%Blazer%"

    View Slide

  32. Filter
    vs
    Query

    View Slide

  33. Filter
    •Does it match? Yes or no
    •When relevance doesn’t matter
    •Faster & cacheable
    •For non-analyzed data
    Query
    •How well does it match?
    •For full-text search
    •On analyzed/tokenized data

    View Slide

  34. Match Query
    Multi Match Query
    Bool Query
    Boosting Query
    Common Terms Query
    Constant Score Query
    Dis Max Query
    Filtered Query
    Fuzzy Like This Query
    Fuzzy Like This Field Query
    Function Score Query
    Fuzzy Query
    GeoShape Query
    Has Child Query
    Has Parent Query
    Ids Query
    Indices Query
    Match All Query
    More Like This Query
    Nested Query
    Prefix Query
    Query String Query
    Simple Query String Query
    Range Query
    Regexp Query
    Span First Query
    Span Multi Term Query
    Span Near Query
    Span Not Query
    Span Or Query
    Span Term Query
    Term Query
    Terms Query
    Top Children Query
    Wildcard Query
    Minimum Should Match
    Multi Term Query Rewrite
    Template Query

    View Slide

  35. And Filter
    Bool Filter
    Exists Filter
    Geo Bounding Box Filter
    Geo Distance Filter
    Geo Distance Range Filter
    Geo Polygon Filter
    GeoShape Filter
    Geohash Cell Filter
    Has Child Filter
    Has Parent Filter
    Ids Filter
    Indices Filter
    Limit Filter
    Match All Filter
    Missing Filter
    Nested Filter
    Not Filter
    Or Filter
    Prefix Filter
    Query Filter
    Range Filter
    Regexp Filter
    Script Filter
    Term Filter
    Terms Filter
    Type Filter

    View Slide

  36. Filter
    examples

    View Slide

  37. POST  /products/product/_search?pretty  
    {  
       "query":  {  
           "filtered":  {  
               "filter":  {  
                   "ids":  {  
                       "values":  [231,234,258]  
                   }  
               }  
           }  
       }  
    }
    SELECT  *  FROM  
    products.product    
    WHERE    
    entity_id  IN  
    (231,234,258)

    View Slide

  38. POST  /products/product/_search?pretty  
    {  
       "query":  {  
           "filtered":  {  
               "filter":  {  
                   "bool":  {  
                       "must":  [  
                           {  
                               "range":  {  
                                   "price":  {  
                                       "gte":  100,  
                                       "lte":  400  
                                   }  
                               }  
                           }  
                       ],  
                       "must_not":  [  
                           {  
                               "term":  {  
                                   "name":  "Convertible  Dress"  
                               }  
                           }  
                       ],  
                       "should":  [  
                           {  
                               "term":  {  
                                   "category":  "Women"  
                               }  
                           },  
                           {  
                               "term":  {  
                                   "category":  "New  Arrivals"  
                               }  
                           }  
                       ]  
                   }  
               }  
           }  
       }  
    }
    SELECT  *  FROM  
    products.product    
    WHERE    
    price  BETWEEN  100  AND  
    400  AND  
    name  !=  "Convertible  
    Dress"  AND  
    (category  =  "Women"  
    OR  category  =  "New  
    Arrivals")

    View Slide

  39. POST  /products/product/_search?pretty  
    {  
       "query":  {  
           "filtered":  {  
               "filter":  {  
                   "prefix":  {  
                       "name":  "Slim"  
                   }  
               }  
           }  
       }  
    }
    SELECT  *  FROM  
    products.product    
    WHERE    
    name  LIKE  "Slim%"

    View Slide

  40. {  
           "filtered"  :  {  
                   "filter"  :  {  
                           "geo_distance_range"  :  {  
                                   "from"  :  "200km",  
                                   "to"  :  "400km",  
                                   "pin.location"  :  {  
                                           "lat"  :  40,  
                                           "lon"  :  -­‐70  
                                   }  
                           }  
                   }  
           }  
    }
    Requires “geo
    point” typed
    field

    View Slide

  41. Relevance

    View Slide

  42. {  
         "took":  1,  
         "timed_out":  false,  
         "_shards":  {  
               "total":  1,  
               "successful":  1,  
               "failed":  0  
         },  
         "hits":  {  
               "total":  2,  
               "max_score":  3.3350093,  
               "hits":  [  
                     {  
                           "_index":  "products",  
                           "_type":  "product",  
                           "_id":  "243",  
                           "_score":  3.3350093,  
                           "fields":  {  
                                 "name":  [  
                                       "Linen  Blazer"  
                                 ]  
                           }  
                     },  
                     {  
                           "_index":  "products",  
                           "_type":  "product",  
                           "_id":  "246",  
                           "_score":  0.5954286,  
                           "fields":  {  
                                 "name":  [  
                                       "Stretch  Cotton  Blazer"  
                                 ]  
                           }  
                     }  
               ]  
         }  
    }
    POST  /products/product/_search?pretty  
    {  
       "fields":  ["name"],    
       "query":  {  
           "match":  {  
               "name.raw":  "Linen  Blazer"  
           }  
       }  
    }
    Hits both
    terms. More
    relevant

    View Slide

  43. {  
         "took":  1,  
         "timed_out":  false,  
         "_shards":  {  
               "total":  1,  
               "successful":  1,  
               "failed":  0  
         },  
         "hits":  {  
               "total":  1,  
               "max_score":  1,  
               "hits":  [  
                     {  
                           "_index":  "products",  
                           "_type":  "product",  
                           "_id":  "243",  
                           "_score":  1,  
                           "fields":  {  
                                 "name":  [  
                                       "Linen  Blazer"  
                                 ]  
                           }  
                     }  
               ]  
         }  
    }
    POST  /products/product/_search?pretty  
    {  
       "query":  {  
           "filtered":  {  
               "query":  {  
                   "match_all":  {}  
               },  
               "filter":  {  
                   "term":  {  
                       "name":  "Linen  Blazer"  
                   }  
               }  
           }  
       }  
    }
    No relevance
    on filters
    Score is
    always 1

    View Slide

  44. POST  /products/product/_search?pretty  
    {  
       "fields":  ["name","description"],    
       "query":  {  
           "bool":  {  
               "must":  [  
                   {  
                       "match":  {  
                           "description.raw":  "suit"  
                       }  
                   }  
               ],  
               "should":  [  
                   {  
                       "match":  {  
                           "name.raw":  "coat"  
                       }  
                   }  
               ]  
           }  
       }  
    }
    Only search
    for “suit”
    Increase
    relevance if name
    contains “coat”

    View Slide

  45. POST  /products/product/_search?pretty  
    {  
       "fields":  ["price","name","description","category"],    
       "query":  {  
           "bool":  {  
               "must":  [  
                   {  
                       "filtered":  {  
                           "filter":  {  
                               "bool":  {  
                                   "must":  [  
                                       {  
                                           "range":  {  
                                               "price":  {  
                                                   "gte":  100,  
                                                   "lte":  400  
                                               }  
                                           }  
                                       },  
                                       {  
                                           "term":  {  
                                               "category":  "Men"  
                                           }  
                                       }  
                                   ]      
                               }  
                           }  
                       }  
                   }  
               ],  
               "should":  [  
                   {  
                       "match":  {  
                           "category":  "New  Arrivals"  
                       }  
                   }                  
               ]  
           }  
       }  
    }
    Increase
    relevance
    Combined
    filters

    View Slide

  46. POST  /products/product/_search?pretty  
    {  
       "query":  {  
           "bool":  {  
               "must":  [  
                   {  
                       "match_all":  {}  
                   }  
               ],    
               "should":  [  
                   {  
                       "match":  {  
                           "description.raw":  {  
                               "query":  "comfort",  
                               "boost":  2  
                           }  
                       }  
                   },  
                   {  
                       "match":  {  
                           "name.raw":  {  
                               "query":  "tee",  
                               "boost":  3  
                           }  
                       }  
                   }                  
               ]  
           }  
       }  
    }
    Increase
    relevance
    Query-
    time
    boosting

    View Slide

  47. Multi index
    multi type

    View Slide

  48. SELECT  *    
    FROM  *.tbl_a*    
    WHERE    
    key  LIKE  ‘%val%’
    •Cross-database queries
    •Wildcard database
    queries
    •Wildcard table queries
    Not
    supported
    in SQL

    View Slide

  49. /_search  
    /products/_search  
    /products/product/_search  
    /products,clients/_search  
    /pro*/_search  
    /pro*,cli*/_search  
    /products/product,invoice/_search  
    /products/pro*/_search  
    /_all/product/_search  
    /_all/product,invoice/_search  
    /_all/pro*/_search  

    View Slide

  50. Multi
    “all the
    things”

    View Slide

  51. Aggregations

    View Slide

  52. Group by on steroids

    View Slide

  53. SELECT  COUNT(category)    
    FROM  products.product  
    GROUP  BY  category  
    Aggregations
    in SQL
    Metric
    Bucket

    View Slide

  54. SELECT  COUNT(category)    
    FROM  products.product  
    GROUP  BY  category  
    POST  /products/product/_search?
    pretty&search_type=count  
     {  
       "aggs":  {  
           "number_of_categories"  :  {  
               "cardinality":  {  
                   "field":  "category"  
               }  
           }  
       }  
    }
    Metric
    Bucket
    Only
    aggs, no
    docs

    View Slide

  55. POST  /products/product/_search?pretty  
     {  
       "fields":  ["category","price","name"],    
       "query":  {  
         "match":  {  
             "name.raw":  "blazer"  
         }  
       },  
       "aggs":  {  
           "avg_price":  {  
               "avg":  {  
                   "field":  "price"  
               }  
           },  
           "min_price"  :  {  
               "min":  {  
                   "field":  "price"  
               }  
           },  
           "max_price"  :  {  
               "max":  {  
                   "field":  "price"  
               }  
           },  
           "number_of_products_per_category"  :  {  
               "terms":  {  
                   "field":  "category",  
                   "size":  10  
               }  
           }  
       }  
    }
    Multi-group
    by
    besides
    query

    View Slide

  56.      "aggregations":  {  
               "min_price":  {  
                     "value":  455  
               },  
               "number_of_products_per_category":  {  
                     "doc_count_error_upper_bound":  0,  
                     "sum_other_doc_count":  0,  
                     "buckets":  [  
                           {  
                                 "key":  "Blazers",  
                                 "doc_count":  2  
                           },  
                           {  
                                 "key":  "Default  Category",  
                                 "doc_count":  2  
                           },  
                           {  
                                 "key":  "Men",  
                                 "doc_count":  2  
                           }  
                     ]  
               },  
               "max_price":  {  
                     "value":  490  
               },  
               "avg_price":  {  
                     "value":  472.5  
               }  
         }
    Aggregation
    output
    Drill
    down
    search

    View Slide

  57. Min Aggregation
    Max Aggregation
    Sum Aggregation
    Avg Aggregation
    Stats Aggregation
    Extended Stats Aggregation
    Value Count Aggregation
    Percentiles Aggregation
    Percentile Ranks Aggregation
    Cardinality Aggregation
    Geo Bounds Aggregation
    Top hits Aggregation
    Scripted Metric Aggregation
    Global Aggregation
    Filter Aggregation
    Filters Aggregation
    Missing Aggregation
    Nested Aggregation
    Reverse nested Aggregation
    Children Aggregation
    Terms Aggregation
    Significant Terms Aggregation
    Range Aggregation
    Date Range Aggregation
    IPv4 Range Aggregation
    Histogram Aggregation
    Date Histogram Aggregation
    Geo Distance Aggregation
    GeoHash grid Aggregation

    View Slide

  58. Managing
    Elasticsearch

    View Slide

  59. Plenty of ways
    … for which we don’t have enough time

    View Slide

  60. Clustering

    View Slide

  61. Single
    node
    2 node
    cluster
    3 node
    cluster

    View Slide

  62. Example config settings
    node.rack:    my-­‐location  
    node.master:  true  
    node.data:  true  
    http.enabled:  true  
    cluster.name:  my-­‐cluster  
    node.name:  my-­‐node  
    index.number_of_shards:  5  
    index.number_of_replicas:  1  
    discovery.zen.minimum_master_nodes:  2

    View Slide

  63. GET /_cat

    View Slide

  64. GET  /_cat  
    =^.^=  
    /_cat/allocation  
    /_cat/shards  
    /_cat/shards/{index}  
    /_cat/master  
    /_cat/nodes  
    /_cat/indices  
    /_cat/indices/{index}  
    /_cat/segments  
    /_cat/segments/{index}  
    /_cat/count  
    /_cat/count/{index}  
    /_cat/recovery  
    /_cat/recovery/{index}  
    /_cat/health  
    /_cat/pending_tasks  
    /_cat/aliases  
    /_cat/aliases/{alias}  
    /_cat/thread_pool  
    /_cat/plugins  
    /_cat/fielddata  
    /_cat/fielddata/{fields}  
    Non-JSON
    output

    View Slide

  65. GET  /_cat/shards?v  
    index        shard  prirep  state      docs  store  ip                          node      
    my-­‐index  2          r            STARTED        6  7.2kb  192.168.10.142  node3    
    my-­‐index  2          p            STARTED        6  9.5kb  192.168.10.142  node2    
    my-­‐index  0          p            STARTED        4  7.1kb  192.168.10.142  node3    
    my-­‐index  0          r            STARTED        4  4.8kb  192.168.10.142  node2    
    my-­‐index  3          r            STARTED        5  7.1kb  192.168.10.142  node1    
    my-­‐index  3          p            STARTED        5  7.2kb  192.168.10.142  node3    
    my-­‐index  1          p            STARTED        1  2.4kb  192.168.10.142  node1    
    my-­‐index  1          r            STARTED        1  2.4kb  192.168.10.142  node2    
    my-­‐index  4          p            STARTED        5  9.5kb  192.168.10.142  node1    
    my-­‐index  4          r            STARTED        5  9.4kb  192.168.10.142  node3  
    5 shards & a
    single replica
    by default

    View Slide

  66. GET  /_cat/health?
    v&h=cluster,status,node.total,shards,pri,unassign,init  
    cluster      status  node.total  shards  pri  unassign  init    
    mycluster  green                      3          12      6                0        0    
    Cluster health

    View Slide

  67. The ELK stack

    View Slide

  68. View Slide

  69. Logs
    Parse
    & ship
    Store
    Visualize

    View Slide

  70. View Slide

  71. Integrating
    Elasticsearch

    View Slide

  72. It’s REST, deal
    with it!
    Directly
    from
    Javascript?
    Don’t
    forget to
    “restrict”
    access
    AJAX #FTW
    Behind a
    proxy
    No
    backend
    code

    View Slide

  73. Or just use a
    backend API
    PHP Java Perl
    Python
    Ruby
    .NET

    View Slide

  74. View Slide