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

ElasticSearch In Action - Zendcon15

Thijs Feryn
October 22, 2015

ElasticSearch In Action - Zendcon15

Slides for my ElasticSearch presentation at Zendcon 2015 in Las Vegas

Thijs Feryn

October 22, 2015
Tweet

More Decks by Thijs Feryn

Other Decks in Technology

Transcript

  1. Elasticsearch
    in action
    By Thijs Feryn

    View full-size slide

  2. Explain in 1 slide

    View full-size 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 full-size slide

  4. Still with me?

    View full-size slide

  5. Hi, I’m Thijs

    View full-size slide

  6. I’m
    @ThijsFeryn
    on Twitter

    View full-size slide

  7. I’m an
    Evangelist
    At

    View full-size slide

  8. I’m a
    at
    board member

    View full-size slide

  9. https://joind.in/talk/view/15627
    I need
    feedback

    View full-size slide

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

    View full-size slide

  11. {  
       "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 full-size slide

  12. RDBMS Elasticsearch
    Database
    Table
    Row
    Index
    Type
    Document

    View full-size slide

  13. 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 full-size slide

  14. 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 full-size slide

  15. 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 full-size slide

  16. Explicit mapping
    … using actual data

    View full-size slide

  17. 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 full-size slide

  18. Import data
    from MySQL to
    ElasticSearch

    View full-size slide

  19. {  
           "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 full-size slide

  20. 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 full-size slide

  21.      "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 full-size slide

  22. Analyzed
    vs
    non-analyzed

    View full-size slide

  23. Full-text
    vs
    exact value

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  26. 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 full-size slide

  27. 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size slide

  32. Filter
    vs
    Query

    View full-size 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 full-size 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 full-size 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 full-size slide

  36. Filter
    examples

    View full-size 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 full-size 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  41. {  
         "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 full-size slide

  42. {  
         "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 full-size slide

  43. 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 full-size slide

  44. 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 full-size slide

  45. 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 full-size slide

  46. Multi index
    multi type

    View full-size slide

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

    View full-size slide

  48. /_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 full-size slide

  49. Multi
    “all the
    things”

    View full-size slide

  50. Aggregations

    View full-size slide

  51. Group by on steroids

    View full-size slide

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

    View full-size slide

  53. 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 full-size slide

  54. 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 full-size slide

  55.      "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 full-size slide

  56. 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 full-size slide

  57. Managing
    Elasticsearch

    View full-size slide

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

    View full-size slide

  59. Single
    node
    2 node
    cluster
    3 node
    cluster

    View full-size slide

  60. 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 full-size slide

  61. 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 full-size slide

  62. 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 full-size slide

  63. 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 full-size slide

  64. The ELK stack

    View full-size slide

  65. Logs
    Parse
    & ship
    Store
    Visualize

    View full-size slide

  66. Integrating
    Elasticsearch

    View full-size slide

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

    View full-size slide

  68. Or just use an
    API
    PHP Java Perl
    Python
    Ruby
    .NET

    View full-size slide

  69. Since this is a PHP
    conference …

    View full-size slide

  70. Composer #FTW
    {  
           "require":  {  
                   "elasticsearch/elasticsearch":  "~1.0"  
           }  
    }
    https://github.com/elastic/elasticsearch-php

    View full-size slide

  71. require 'vendor/autoload.php';
    $connectionParams['hosts'] = array (
    'elastic001',
    'elastic002',
    'elastic003',
    'elastic004',
    'elastic005',
    );
    $client = new Elasticsearch\Client($connectionParams);
    $searchParams['index'] = 'myIndex';
    $searchParams['type'] = 'myType';
    $searchParams['body'] = '{"from":0,"size":"1000","query":{"filtered":
    {"query":{"match_all":{}},"filter":{"and":[{"range":{"timestamp"
    :
    {"from":"2015-06-22T00:00:00Z","to":"2015-06-22T23:59:59Z"}}}]}}},"so
    rt":[{"timestamp":{"order":"desc"
    }}],"facets":{"resultspread":{"terms":{"field":"result"}}}}';
    $results = $client->search($searchParams);
    echo $results['hits']['hits'][0]["_source"]["rcpt"];

    View full-size slide

  72. https://joind.in/talk/view/15627
    I need
    feedback

    View full-size slide