О докладчике

Дмитрий Голушко
 Java разработчик, server-side
Важные параметры:
Скорость индексирования(в том числе realtime)

Способы взаимодействия(API, REST, etc.)
Работа с языками, стемминг, нечеткие запросы

Дополнительные типы полей в
документах(numeric, geo, source, etc.)

Платформа и язык
Встроенные механизмы ранжирования и сортировки
Какие есть варианты?
Elasticsearch(based on Lucene, Java)
Solr(based on Lucene, Java)

Sphinx search engine(C++)
Xapian(C++)
Почему мы выбрали Elasticsearch?
Отличная поддержка шардинга и репликации на лету
Шардинг и репликация.
       Создаем индекс.
Нода 1
 Street1   {
 Street2       “number_of_shards” : 2,
               “number_of_replicas” : 1
           }
Шардинг и репликация.
 Добавляем еще одну ноду.
Нода 1                  Нода 2
           Репликация
 Street1                 Street1
 Street2                 Street2
Шардинг и репликация.
           Добавляем еще 2 ноды.
Нода 1         Нода 2     Нода 3     Нода 4
 Street1                   Street1
                Street2               Street2
Почему мы выбрали Elasticsearch?

Отличная поддержка шардинга и репликации на лету
Написан на Java и базируется на известном движке
Lucene
Near-realtime индексация.
Поиск по «свежему» индексу
Поиск по индексу, с
одновременной индексацией
Поиск по большому индексу, с
одновременной индексацией
Почему мы выбрали Elasticsearch?
Отличная поддержка шардинга и репликации на лету
Написан на Java и базируется на известном движке
Lucene
Near-realtime индексация.
 Есть всё что нам нужно
Opensource, ASL v2
Имеется возможность для расширения
Возможность для расширения
River-плагины(поток данных из другого источника)
     CouchDB     RabbitMQ     MongoDB       …
Анализаторы
     Русская морфология     Hunspell(орфография)
Transport(расширения протоколов взаимодействия)
     Memcached     ZeroMQ     Servlet   …
Site Plugins(чаще всего UI для управления кластером)

Scripting Plugins(ЯП для скриптов)
ElasticSearch Paramedic
BigDesk
elasticsearch-head
Особенности Elasticsearch
Документно-ориентированный
Schema-free
JSON как основной способ работы с данными
JSON как основной способ работы с данными


GET “http://localhost:9200/index_name/streets/_search?q=Жукова”
{                                              Затраченное время
    "took" : 138,
    "timed_out" : false,
     "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 },
        "hits" : {                                           Количество результатов
          "total" : 1,
          "max_score" : 1.9674579,
          "hits" : [{
            "_index" : “index_name",                                Исходный документ
            "_type" : "street",
            "_id" : "VLvO7h7bQUiCOlGwd2iJrA",
            "_score" : 1.9674579,
            "_source" : {"STREET_NAME":"Маршала Жукова", "CITY_NAME":"Омск", “STREET_ID” : 3}
           }]
       }
}
Особенности Elasticsearch
Документно-ориентированный
Schema-free
JSON как основной способ работы с данными
Распределенный поиск
Распределенный поиск

Node           Node   Node




Node           Node   Node




         Приложение
Распределенный поиск

Node           Node   Node




Node           Node   Node




         Приложение
Особенности Elasticsearch
Документно-ориентированный
Schema-free
JSON как основной способ работы с данными
Распределенный поиск
Скрипты для фильтрации(о них чуть позже)
Обновление настроек «на лету»
Обновление настроек «на лету»
POST “http://localhost:9200/index_name/_settings”

"{
     "index" : {
        "number_of_replicas" : 3
     }
}
Обновление настроек на лету

Нода 1     Нода 2     Нода 3     Нода 4
 Street1    Street1    Street1    Street1
 Street2    Street2    Street2    Street2
Индексация

              Анализатор

                                                    Token Filter
Tokenizer
                                     Token Filter

                      Token Filter


       Token Filter
Token Filters
Стеммеры(Стеммер Портера)
    важно             важн
    важного           важн
    важное            важн
    важной            важн
    важном            важн
    важному           важн

Фонетические(Soundex, Metaphone, etc.)
Ngramm
Soundex
• Первая буква сохраняется
• В остальной части слова:
    • Буквы, обозначающие, как правило,
    гласные звуки: a, e, h, i, o, u, w и y — отбрасываются
    • Оставшиеся буквы (согласные) заменяются на цифры от 1 до 6,
    причём похожим по звучанию буквам соответствуют одинаковые цифры:
         • 1: b, f, p, v
         • 2: c, g, j, k, q, s, x, z
         • 3: d, t
         • 4: l
         • 5: m, n
         • 6: r
    • Любая последовательность одинаковых цифр сокращается до одной такой цифры.
• Итоговая строка обрезается до первых четырёх символов.
Если длина строки меньше требуемой, недостающие символы заменяются знаком 0.
Примеры:
аmmonium → ammnm → a5555 → a5 → a500
implementation → implmnttn → i51455335 → i514535 → i514
Ngramm
Запросы
«Обычные» запросы
Term MatchNot match Prefix Bool Wildcard Range
Географические запросы
Boosting запросы
Span запросы
Нечеткие запросы
Fuzzy запросы(нечеткие)
Расстояние Левенштейна - минимальное количество операций
      вставки одного символа, удаления одного символа и замены
      одного символа на другой, необходимых для превращения
      одной строки в другую.


       Жукава
                                 1                Жукова

     Лизной (проезд)
                                   2          Лесной (проезд)

       Бухольца
                                  1               Бухгольца
Это важно!
В большинстве случаев вы должны использовать для поиска
    тот же алгоритм анализа, что и при индексировании!


       Fuzzy Query              Soundex
        «жукава»                «a500»


      Fuzzy Query                  3gramm
       «жукава»                «жук ука кав ава»
Фильтрация
Обычные фильтры
Term Prefix Range MissingExists Query

Геофильтры
Script фильтр
Геофильтры
    Geo BBox   Geo distance   Geo distance range   Geo polygon   Geo shape



{                                {
    “address" : {                    "location" : {
        "location" : {                  "type" : "envelope",
            "lat" : 41.12,              "coordinates" : [[-45.0, 45.0],
            "lon" : -71.34                               [45.0, -45.0]]
         }                           }
      }                          }
}
Геофильтры
Geo BBox   Geo distance   Geo distance range   Geo polygon   Geo shape



 "filter" : {
       "geo_bounding_box" : {
         "pin.location" : {
             "top_left" : {"lat" : 40.73, "lon" : -74.1 },
             "bottom_right" : {"lat" : 40.717, "lon" : -73.99}
         }
       }
    }
Геофильтры
Geo BBox   Geo distance   Geo distance range   Geo polygon   Geo shape
Геофильтры
Geo BBox   Geo distance   Geo distance range   Geo polygon   Geo shape



            "filter" : {
                    "geo_distance" : {
                        "distance" : "2km",
                        "pin.location" : {
                          "lat" : 40,
                          "lon" : -70
                        }
                    }
                  }
Геофильтры
Geo BBox   Geo distance   Geo distance range   Geo polygon   Geo shape
Геофильтры
Geo BBox    Geo distance   Geo distance range   Geo polygon   Geo shape

           "filter": {
                "geo_shape": {
                  "location": {
                     "indexed_shape": {"id": "Украина",
                         "type": "countries",
                         "index": "shapes",
                         "shape_field_name": "shape"
                      },
                     "relation": "within"
                   }
                }
           }
Скрипт-фильтр
"filtered" : {
   "query" : {
      ...
   },
   "filter" : {
      "script" : {
          "script" : "doc['num1'].value > 1"
      }
   }
}
Скрипт-фильтр. Доступные языки

           Java
        JavaScript
          Groovy
          Python
Advanced features
Подсветка(Highlighting)
Именованные фильтры(Named Filters)
Attachment indexing(с помощью Apache Tika)
Microsoft Office, Open Document Formats, ePub, PDF, etc.

Time-to-live fields
Percolation
Facets
Percolation

  Индексируются запросы, а не документы!

      Тем не менее это обычный индекс
  Запросы распространяются на все реплики

Поддерживают все обычные запросы и фильтры
Percolation
POST “http://localhost:9200/_percolator/messages/kgb”

        {
            "query" : {
               "terms" : {
                "message" : ["путин","навальный",
                   "террорист","бомба",
                   "наркотики","взятка"]
                }
             }
        }
Здарова! Зацени чо творится
"doc" : {                     «Одесский террорист, "метивший
    "message" : "..."         в Путина",
                              заявил о милицейских пытках
  }                           наркотиками и пакетами».




  GET “http://localhost:9200/messages/type/_percolate”




         {"ok":true, "matches":["kgb"]}
Facets
 Агрегированная информация по запросу
        Статистическая информация
    Сумма, минимальноемаксимальное значение, среднее и т.д.


Гистограммы(включая гистрограмму по дате)
              Географический facet
Географический facet
 {
     "facets" : {
       "geo1" : {
         "geo_distance" : {
            "pin.location" : {"lat" : 40, "lon" : -70 },
            "ranges" : [
               { "to" : 10 },
               { "from" : 10, "to" : 20 },
               { "from" : 20, "to" : 100 },
               { "from" : 100 }
            ]
         }
       }
     }
 }
А теперь небольшой real-world пример!
Развлечения!
{
    "query" : {
            "match_all" : {}
     },
    "facets" : {
      "facet_search" : {
         "terms" : {
           "quick_address_type" : ["restaurant",
                           "cafe",
                           "sauna",
                           "pool",
                           "bowling","bar"]
         }
       }
    }
}
"facets" : {
  "tags" : {
    "_type" : "terms",
    "missing" : 0,
    "total": 30,
    "other": 0,
    "terms" : [ { "term" : "restaurant", "count" : 7 },
               {"term" : "cafe", "count" : 5 },
               {"term" : "sauna","count" : 6},
               {"term" : "pool","count" : 3},
               {"term" : "bowling","count" : 2},
               {"term" : "bar","count" : 7 } ]
  }
}
Рестораны(7)
Кафе(5)
Сауны(6)
Бильярды(3)
Боулинги(2)
Бары(7)
{
     "query" : {
          "term" : {"quick_address_type" : "restaurant"}
      },
      "sort" : [
      {
           "_geo_distance" : {
               "pin.location" : [-73.13, 55.01],
               "order" : "asc",
               "unit" : "km"
           }
        },
        {
            "rating" : {
                 "user_rating" : "desc"
             }
        }
    ]
}
«Беляшкино»
 1км.

«Пампуши»
 2км.

«Фуаграшная»
 0,5км.
КОНЕЦ!

2013-02-02 03 Голушко. Полнотекстовый поиск с Elasticsearch