BarCamp BA 2012                    @mgiglesias




          ElasticSearch
         La tenés atroden Google
$ who am i
●   @mgiglesias
●   C++, Node.js, Python, PHP
●   Open source
●   NodoJS y GrupoPHP
●   WORKANA → www.workana.com
En tu cara Google
¿Me ponés un buscadorcito?
● Los que merecen ser exterminados
   – Usá LIKE. Es fácil.
● Los que te odian


   – MySQL FULL TEXT
● Los que piensan que The Matrix está basada en hechos

  reales
   – Creá tu propio indexador
● Los que te quieren. Un poquito nomás.


   – Sphinx
● Los que te quieren ver destronar a Zuckerberg. Y te ayudan


  a hacerlo.
   – ElasticSearch papá.
¿¿¿¿Java == Diversión????
Te empieza a gustar
●   Montado sobre Lucene
●   “Schema-free”
●   REST
    –   ¡Hasta la configuración!
●   Múltiples índices (y poder buscar a través)
●   Casi super requete-recontra real time
●   Super requete-recontra distribuido
●   Una papa de instalar, integrar, y escalar
●   El tipo que lo creó es un loco de la guerra (@kimchy)
Conceptos
●   Nodos
●   Índices
●   Tipos
●   Documentos
<3
           REST
                                         Índice            ID
curl -XPUT 'http://localhost:9200/articulos/articulo/1' -d '{
    "titulo": "Buenas cervezas",               Tipo
    "contenido": "Todas. Menos Budweiser.",
    "tags": ["cerveza", "budweiser"]
}'

           Le pasás JSON


curl -XGET
 'http://localhost:9200/articulos/articulo/_search?q=cerveza&pretty'
                                                  API
                      Te devuelve JSON
Obtener documento

curl -XGET 'http://localhost:9200/articulos/articulo/1?pretty'




          {
              "_index" : "articulos",
              "_type" : "articulo",
              "_id" : "1",
              "_version" : 1,
              "exists" : true,
              "_source" : {
                "titulo":"Buenas cervezas",
                "contenido":"Todas. Menos Budweiser."
          }
Actualizar documento

curl -XPUT 'http://localhost:9200/articulos/articulo/1' -d '{
    "titulo": "Buenas cervezas",
    "contenido": "Todas. Menos Budweiser. Tampoco Schneider.",
    "tags" ["cerveza", "budweiser", "schneider"]
}'




                   {
                       "ok":true,
                       "_index":"articulos",
                       "_type":"articulo",
                       "_id":"1",
                       "_version":2
                   }
¿Simplemente un buscador?


curl -XGET 'http://localhost:9200/_all/articulo/_search?q=cerveza'


                                 Busco todos los índices




curl -XGET
  'http://localhost:9200/articulos/articulo,autor/_search?q=name:X'


                       Busco varios tipos de datos
Tipos de datos
●   Quiero tener algunos elementos del documento
    no indexables
●   Quiero poder buscar, agregar filtros, y ordenar
●   Datos simples: string, integer, long, float, double,
    boolean, null
●   Datos compuestos: array, object
●   boost
●   include_in_all
0, 0, 0

curl -XDELETE 'http://localhost:9200/articulos'

curl -XPUT 'http://localhost:9200/articulos'

curl -XPUT 'http://localhost:9200/articulos/articulo/_mapping' -d '{
    "articulo": { "properties": {
        "titulo": {"type":"string"},
        "pais": {"type":"string", "include_in_all":false},
        "contenido": {"type":"string"},
        "publicado": {"type":"date", "format": "yyyy-MM-dd HH:mm:ss"},
        "tags": {"type":"string"},
        "rating": {"type":"object", "properties":{
            "promedio": {"type": "float"},
            "total": {"type": "long"}
        }}
    }}
}'
Filtros

curl -XPUT 'http://localhost:9200/articulos/articulo/1' -d '{
    "titulo": "Buenas cervezas",
    "contenido": "Todas. Menos Budweiser.",
    "publicado": "2012-11-04 06:43:00",
    "tags": ["cerveza", "budweiser"],
    "rating": {"promedio": 8.7, "total": 15}
}'

curl -XGET 'http://localhost:9200/articulos/articulo/_search?q=cerveza' -d '{
    "filter": {
        "range": {"rating.total": {"from": 10}}
    }
}'
Filtros
●   limit
●   and, or, not
●   exists
●   geo_distance, geo_distance_range,
    geo_bbox, geo_shape, …
●   range, numeric_range
●   has_parent, has_child
Mejorando la búsqueda
●   Query en el POST
●   query_string
●   field
●   bool: must, must_not
●   fuzzy
●   wildcard
Facets
Rivers
●   Consume datos (los trae o los recibe) y los mete en ES
●   Rivers
    –   CouchDB
    –   RabbitMQ
    –   Twitter
    –   Wikipedia
●   Community
    –   MongoDB
    –   JDBC
Percolator
●   Almaceno una query (en un índice)
●   Ejecuto esa query (_percolate) sobre un documento
    –   ¡No almacena el documento en el índice!
●   Me dice que queries matchearon
●   Ejemplo: tweets que matcheen una búsqueda, a
    medida que vienen
●   Como almaceno queries, puedo filtrar que queries
    se ejecutan (wow)
Super requete-recontra escalable
●   Shards: parte de los documentos (cada uno es un
    índice Lucene). Se shardea por _id
    –   En cuantas “partes” queremos dividir los datos
    –   Si un nodo se cae, todavía tenemos parte de los datos
    –   Más shards, mejor indexing
●   Cada shard puede tener réplicas (que se pueden crear
    dinamicamente!)
    –   Copias. Si se caen varios shards, aun podemos tener toda
        la data
    –   Más replicas, mejor búsqueda
Super requete-recontra escalable


     Shard 1                Replica 1              Shard 2       Replica 2

Articulo 1              Articulo 1            Articulo 2     Articulo 2
Articulo 3              Articulo 3            Articulo 4     Articulo 4




               Query para artículos 1, 2, 4
Una tormenta de magia
●   Discovery: identificar nodos, y seleccionar nodo
    master
●   El master mantiene el estado del cluster, y
    reasigna shards si nodos entran / se van
●   Los nodos responden a los requests (no van a
    master)
●   Un nodo sabe si puede responder un request, y si
    no lo delega
●   Auto-discovery por Zen o EC2
Persistent storage
●   La info sobre un nodo es temporaria
    –   JVM heap (ojo!)
●   Persistent: para estado del cluster e indices
●   Permite un full recovery si se restartea el cluster
●   Gateways soportados:
    –   FS local o compartido
    –   Hadoop via HDFS
    –   S3
API
●   _search: errr... buscar :)
●   _status: te da información sobre un índice
●   _refresh: refrescar indices
●   _optimize: optimizar en Lucene
●   _mapping: crear un tipo de datos
BarCamp BA 2012          @mgiglesias




           ¿Preguntas?

ElasticSearch: la tenés atroden Google

  • 1.
    BarCamp BA 2012 @mgiglesias ElasticSearch La tenés atroden Google
  • 2.
    $ who ami ● @mgiglesias ● C++, Node.js, Python, PHP ● Open source ● NodoJS y GrupoPHP ● WORKANA → www.workana.com
  • 3.
    En tu caraGoogle
  • 4.
    ¿Me ponés unbuscadorcito? ● Los que merecen ser exterminados – Usá LIKE. Es fácil. ● Los que te odian – MySQL FULL TEXT ● Los que piensan que The Matrix está basada en hechos reales – Creá tu propio indexador ● Los que te quieren. Un poquito nomás. – Sphinx ● Los que te quieren ver destronar a Zuckerberg. Y te ayudan a hacerlo. – ElasticSearch papá.
  • 5.
  • 6.
    Te empieza agustar ● Montado sobre Lucene ● “Schema-free” ● REST – ¡Hasta la configuración! ● Múltiples índices (y poder buscar a través) ● Casi super requete-recontra real time ● Super requete-recontra distribuido ● Una papa de instalar, integrar, y escalar ● El tipo que lo creó es un loco de la guerra (@kimchy)
  • 7.
    Conceptos ● Nodos ● Índices ● Tipos ● Documentos
  • 8.
    <3 REST Índice ID curl -XPUT 'http://localhost:9200/articulos/articulo/1' -d '{ "titulo": "Buenas cervezas", Tipo "contenido": "Todas. Menos Budweiser.", "tags": ["cerveza", "budweiser"] }' Le pasás JSON curl -XGET 'http://localhost:9200/articulos/articulo/_search?q=cerveza&pretty' API Te devuelve JSON
  • 9.
    Obtener documento curl -XGET'http://localhost:9200/articulos/articulo/1?pretty' { "_index" : "articulos", "_type" : "articulo", "_id" : "1", "_version" : 1, "exists" : true, "_source" : { "titulo":"Buenas cervezas", "contenido":"Todas. Menos Budweiser." }
  • 10.
    Actualizar documento curl -XPUT'http://localhost:9200/articulos/articulo/1' -d '{ "titulo": "Buenas cervezas", "contenido": "Todas. Menos Budweiser. Tampoco Schneider.", "tags" ["cerveza", "budweiser", "schneider"] }' { "ok":true, "_index":"articulos", "_type":"articulo", "_id":"1", "_version":2 }
  • 11.
    ¿Simplemente un buscador? curl-XGET 'http://localhost:9200/_all/articulo/_search?q=cerveza' Busco todos los índices curl -XGET 'http://localhost:9200/articulos/articulo,autor/_search?q=name:X' Busco varios tipos de datos
  • 12.
    Tipos de datos ● Quiero tener algunos elementos del documento no indexables ● Quiero poder buscar, agregar filtros, y ordenar ● Datos simples: string, integer, long, float, double, boolean, null ● Datos compuestos: array, object ● boost ● include_in_all
  • 13.
    0, 0, 0 curl-XDELETE 'http://localhost:9200/articulos' curl -XPUT 'http://localhost:9200/articulos' curl -XPUT 'http://localhost:9200/articulos/articulo/_mapping' -d '{ "articulo": { "properties": { "titulo": {"type":"string"}, "pais": {"type":"string", "include_in_all":false}, "contenido": {"type":"string"}, "publicado": {"type":"date", "format": "yyyy-MM-dd HH:mm:ss"}, "tags": {"type":"string"}, "rating": {"type":"object", "properties":{ "promedio": {"type": "float"}, "total": {"type": "long"} }} }} }'
  • 14.
    Filtros curl -XPUT 'http://localhost:9200/articulos/articulo/1'-d '{ "titulo": "Buenas cervezas", "contenido": "Todas. Menos Budweiser.", "publicado": "2012-11-04 06:43:00", "tags": ["cerveza", "budweiser"], "rating": {"promedio": 8.7, "total": 15} }' curl -XGET 'http://localhost:9200/articulos/articulo/_search?q=cerveza' -d '{ "filter": { "range": {"rating.total": {"from": 10}} } }'
  • 15.
    Filtros ● limit ● and, or, not ● exists ● geo_distance, geo_distance_range, geo_bbox, geo_shape, … ● range, numeric_range ● has_parent, has_child
  • 16.
    Mejorando la búsqueda ● Query en el POST ● query_string ● field ● bool: must, must_not ● fuzzy ● wildcard
  • 17.
  • 18.
    Rivers ● Consume datos (los trae o los recibe) y los mete en ES ● Rivers – CouchDB – RabbitMQ – Twitter – Wikipedia ● Community – MongoDB – JDBC
  • 19.
    Percolator ● Almaceno una query (en un índice) ● Ejecuto esa query (_percolate) sobre un documento – ¡No almacena el documento en el índice! ● Me dice que queries matchearon ● Ejemplo: tweets que matcheen una búsqueda, a medida que vienen ● Como almaceno queries, puedo filtrar que queries se ejecutan (wow)
  • 20.
    Super requete-recontra escalable ● Shards: parte de los documentos (cada uno es un índice Lucene). Se shardea por _id – En cuantas “partes” queremos dividir los datos – Si un nodo se cae, todavía tenemos parte de los datos – Más shards, mejor indexing ● Cada shard puede tener réplicas (que se pueden crear dinamicamente!) – Copias. Si se caen varios shards, aun podemos tener toda la data – Más replicas, mejor búsqueda
  • 21.
    Super requete-recontra escalable Shard 1 Replica 1 Shard 2 Replica 2 Articulo 1 Articulo 1 Articulo 2 Articulo 2 Articulo 3 Articulo 3 Articulo 4 Articulo 4 Query para artículos 1, 2, 4
  • 22.
    Una tormenta demagia ● Discovery: identificar nodos, y seleccionar nodo master ● El master mantiene el estado del cluster, y reasigna shards si nodos entran / se van ● Los nodos responden a los requests (no van a master) ● Un nodo sabe si puede responder un request, y si no lo delega ● Auto-discovery por Zen o EC2
  • 23.
    Persistent storage ● La info sobre un nodo es temporaria – JVM heap (ojo!) ● Persistent: para estado del cluster e indices ● Permite un full recovery si se restartea el cluster ● Gateways soportados: – FS local o compartido – Hadoop via HDFS – S3
  • 24.
    API ● _search: errr... buscar :) ● _status: te da información sobre un índice ● _refresh: refrescar indices ● _optimize: optimizar en Lucene ● _mapping: crear un tipo de datos
  • 25.
    BarCamp BA 2012 @mgiglesias ¿Preguntas?

Notas del editor

  • #7 * REAL TIME: depende del indice. Refresh de un segundo por defecto
  • #8 * Nodos: concepto similar a DB engine * Indices: concepto similar a bases de datos * Tipos: concepto similar a tabla * Documento: concepto similar a registro
  • #9 * REST: PUT versus POST: POST puedo no especificar ID, y me genera uno. PUT si o si tengo que tener ID. * REST: si pongo -XDELETE, borro el documento
  • #10 * Porque? Porque puedo meter data complicada en el documento
  • #11 * Como seria borrar? -XDELETE
  • #13 * boost: levantar relevancia de un campo. Ejemplo: skills en Workana
  • #14 * Se puede definir index_analyzer y search_analyzer para cambiar como se analiza el texto en el momento de indexar o buscar * Se puede deshabilitar el indexado sobre campos
  • #15 * Es un documento, no tengo porque especificar todos los campos
  • #16 * limit: limito cantidad de registros * exists: que un campo existe * numeric_range: mas rapido que range porque pre-carga datos en memoria * has_parent / has_child: para documentos embebidos
  • #17 * query_string: se puede usar OR, AND * field: como query_string pero para un field especifico * fuzzy: Levenshtein, se puede poner un minimo de similaridad. Para numericos, se transforma en un range
  • #18 * Counts agregados junto con la consulta
  • #21 * Replicas: se usan para query en paralelo
  • #23 ** EL CLUSTER se puede manejar via API! * Zen: default, provee unicast y multicast discovery * EC2: similar a multicast, justamente porque EC2 no es multi-cast friendly
  • #25 * _status: cantidad de operaciones, numero de documentos, de todo * _refresh: refrescar explicitamente uno o más indices. Las capacidades real time dependen del tipo de engine usado en el índice: por ejemplo robin requiere llamada a refresh (se llama periodicamente)