Говоря о технологии и практике ES

задняя часть база данных Lucene

ES — это распределенное хранилище на основе Lucene. Lucene предоставляет функцию полнотекстового поиска. ES добавляет к этому механизм распределенного индексирования, предоставляя такие функции, как сегментирование данных, репликация данных и синхронизация данных для обеспечения безопасности данных.

Базовой единицей хранилища ES является документ, который эквивалентен записи в базе данных.Документ включает в себя несколько полей (эквивалентных полям), и Документы могут добавлять или удалять поля в любое время.

Кроме того, ES может быть проиндексирован для полей, которые необходимо получить, чтобы можно было легко получить документ.

Интерфейс API:

В настоящее время поддерживает:

1. Собственный клиентский доступ ES (более быстрый) Версия ES 1.7 требует JDK 1.7 или выше.С 20 января 2016 г. по электронной почте запрашивается кластер ES версии 2.1.0.

2. HTTP-доступ (медленнее);

Указательные документы

_index, _type и _id документа однозначно идентифицируют документ, мы можем предоставить собственный идентификатор или позволить индексу автоматически генерироваться

Укажите идентификатор:

PUT /website/blog/123

Автоматически сгенерированный идентификатор:

POST /{index}/{type}/{id}

В каждом документе в Elasticsearch есть номер версии, и каждый раз, когда вы изменяете документ (в том числе удаляете), _ версия значения увеличивается,

поиск документа

GET/website/blog/123?pretty

Поиск части документа

GET/website/blog/123?_source=title,text

Получает только поле _source, метаданные не требуются

GET /website/blog/123/_source

Если вы просто хотите проверить, существует ли документ — вообще не заботьтесь о содержании — тогда используйте метод HEAD вместо метода GET. Запрос HEAD не имеет возвращаемого тела, только заголовок HTTP-запроса:

curl -i -XHEAD http://localhost:9200/website/blog/123

Если документ существует, Elasticsearch вернет код состояния 200 ok:

Если документ не существует, Elasticsearch вернет код состояния 404 Not Found:

Обновите весь документ:

Внутри Elasticsearch пометил старый документ как удаленный и добавил новый. Хотя вы больше не можете получить доступ к старой версии документа, она не исчезает сразу.На самом деле ES выполняет следующий процесс точно так же, как и раньше:

  1. Создал JSON из старого документа

  2. Изменен JSON

  3. Удалены старые документы

  4. индексировать новый документ

Единственное отличие состоит в том, что API обновления реализует эти шаги только с одним клиентским запросом, без отдельных запросов на получение и индексирование.

Создать новый документ

Подтвердите создание нового документа (невозможно перезаписать существующий документ)

Самый простой способ убедиться, что новый документ создан, — это заставить Elasticsearch автоматически генерировать уникальный _id, используя форму запроса индекса POST.

Если идентификатор уже есть, то вы должны сказать ES, чтобы он принял наш запрос индекса только тогда, когда такие же _index и _type и _id не существуют.Двумя способами:

  1. Используйте параметр строки запроса op_type:

  1. заключается в использовании /_create в конце URL-адреса:

Если запрос на создание нового документа выполнен успешно, ES вернет HTTP-ответ 201 Created с метаданными. С другой стороны, если есть тот же документ, ES вернет код ответа 409 Conflict.

удалить документ

DELETE /website/blog/123

Если документ будет найден, Elasticsearch вернет код HTTP-ответа 200 ok и тело ответа со структурой, подобной следующей. Обратите внимание, что значение поля _version увеличивается.

Если документ не найден, мы получим код ответа 404 Not Found и тело ответа, подобное этому:

_version все равно будет увеличиваться

урегулировать конфликт

Независимо от того, какой документ был проиндексирован последним, он будет уникальным образом сохранен в Elasticsearch. Если другие люди одновременно внесут изменения в этот документ, их изменения будут потеряны. Хотя вероятность того, что два человека изменят один и тот же документ одновременно, очень мала, а случайная его потеря не является серьезной проблемой для нашего бизнеса, но иногда потеря сдачи является серьезной (срочные продажи, рекламные акции и т. д.)

Пессимистический контроль параллелизма:

Этот метод широко используется в реляционных базах данных. Предполагается, что могут возникнуть конфликты изменения, поэтому блокирующий доступ предотвращает конфликты. Типичный пример - заблокировать ряд данных, прежде чем прочитать его, чтобы убедиться, что только резьба, размещенная замок, может модифицировать ряд данных.

Оптимистичный контроль параллелизма:

Использование этого подхода в ES предполагает, что конфликтующие изменения маловероятны и не будут блокировать предпринимаемую операцию, однако, если исходные данные будут изменены во время чтения и записи, обновление не будет выполнено, после чего приложение решает, как разрешить конфликт. Обновления можно повторить, используя новые данные или сообщая о ситуации пользователю.

заявление:

Используйте номер _version, чтобы гарантировать, что конфликтующие изменения в приложении не приведут к потере данных. Мы делаем это, указав номер версии документа, который мы хотим изменить. Если версия не является текущим номером версии, наш запрос не будет выполнен.

Частичное обновление документации

1. Их нельзя модифицировать, только заменить. API обновления должен соответствовать тем же правилам. Извне делаем частичное обновление где-то в документе. Однако внутри API обновления просто использует тот же процесс извлечения-изменения-переиндексации, который описан ранее. Разница в том, что этот процесс происходит внутри сегмента, что позволяет избежать сетевых накладных расходов на несколько запросов. Сокращая время между этапами поиска и переиндексации, мы также уменьшаем вероятность конфликтов из-за изменений в других процессах.

POST /website/blog/1/_update

{

  "doc" : {

     "tags" : [ "testing" ],

     "views": 0

  }

}

2, программирование со сценарием Groovy

Распределенное хранилище документов

алгоритм хранения документов

shard=hash(routing) % number_of_primary_shards

маршрутизация является переменным значением, по умолчанию используется _id документа, также может быть установлено пользовательское значение. Маршрутизация генерирует число с помощью хеш-функции, а затем делит это число на number_of_primary_shards (количество основных сегментов), чтобы получить остаток. Оставшаяся часть этого распределения между 0 и number_of_primary_shards-1 — это расположение сегмента, в котором находится искомый документ.

Как взаимодействуют первичные и вторичные осколки

Реплики одного и того же шарда не будут размещаться на одном узле,

Мы можем отправлять запросы на любой узел в кластере. Каждый узел может обрабатывать произвольные запросы. Каждый узел знает о расположении любого документа в кластере, поэтому он может перенаправлять запросы непосредственно на нужный узел. В приведенном ниже примере все запросы отправляются на узел 1, который мы называем координирующим узлом.

поиск

Пустой поиск

Самая простая форма API поиска — это пустой поиск без указания какого-либо запроса, который просто возвращает все документы по всем индексам в кластере:

GET /_search

Самое главное в возвращаемом результате — это совпадения, которые содержат общее поле для представления общего количества совпадающих документов, а массив совпадений блокирует первые десять документов результата запроса.

Каждый результат в массиве совпадений содержит _index, _type, _id документа, а также поле _source. Это означает, что мы можем использовать весь документ непосредственно из возвращенных результатов поиска. В отличие от других поисковых систем, которые возвращают только идентификатор документа, вам необходимо получить документацию

У каждого результата также есть _source, который измеряет, насколько документ соответствует запросу.По умолчанию наиболее релевантные результаты документа возвращаются первыми, то есть возвращенные документы сортируются в порядке убывания по _score.

Взятое значение говорит нам, сколько миллисекунд потребовалось для выполнения всего поискового запроса.

Значение времени Timed_out сообщает нам, если выходит за счет запроса. По умолчанию запросы поиска не выходят. Если время низкого отклика важнее, чем результаты завершения, вы можете указать тайм-аут 10 или 10 мс (10 миллисекунд) или 1S (1 секунду)

GET /_search?timeout=10ms

Следует отметить, что тайм-аут не останавливает выполнение запроса, он просто говорит координирующему узлу вернуть собранные до сих пор результаты и закрыть соединение. В фоновом режиме другие сегменты могут по-прежнему выполнять запросы даже после отправки результатов. Используйте тайм-ауты, потому что для вас важно SLA (соглашение об уровне обслуживания), а не потому, что вы хотите прервать длительные запросы.

Мультииндексный поиск

Мы можем добиться этого эффекта, указав специальный индекс и введя URL-адрес следующим образом:

/_search ищет все индексы для всех типов

/gb/_search ищет в индексе gb все типы

/gb,us/_search ищет все документы в индексах gb и us

/g*,u*/_search ищет все типы в любом индексе, начинающемся с g или u

/gb/user/_search ищет в индексе gb тип пользователя

/gb,us/user,tweet/_search выполняет поиск в индексах gb и us для типов пользователей и твитов.

/_all/user,tweet/_search выполняет поиск по всем индексам пользователей и типов твитов

Разбивка на страницы:

Точно так же, как SQL использует ключевое слово LIMIT для возврата одной страницы результатов, Elasticsearch принимает параметры from и size:

size

Отображает количество результатов, которые должны быть возвращены, по умолчанию 10.

from

Отображает количество исходных результатов, которые следует пропустить, по умолчанию 0

Если вы показываете 5 результатов на странице, вы можете запросить от 1 до 3 страниц результатов следующим образом:

GET /_search?size=5

GET /_search?size=5&from=5

GET /_search?size=5&from=10

Легкий поиск:

Поиск строки запроса отлично подходит для специальных запросов из командной строки. Например, чтобы запросить все документы, поле твита которых содержит слово elasticsearch в типе твита:

GET/_all/tweet/_search?q=tweet:elasticsearch

Простой поиск _all возвращает все документы, содержащие mary:

GET/_search?q=mary

Поле _all полезно при первой разработке приложения. Позже вы обнаружите, что у вас будет больше контроля над результатами поиска, если вы будете использовать указанное поле вместо поля _all при поиске. Когда поле _all больше не нужно, его можно аннулировать.

Точное значение

Данные в Elasticsearch можно условно разделить на две категории: точные значения и полный текст.

Для точных значений Foo и foo различны, как и 2014 и 2014-09-15.

Точные значения легко запросить. Результат бинарный: либо соответствует запросу, либо нет.

Мы редко делаем точные совпадения в полях полнотекстового типа. Вместо этого мы хотим искать в доменах текстового типа. Мало того, мы хотим, чтобы поиск понимал наше намерение:

  • При поиске UK возвращаются документы, содержащие United Kingdom.

  • Поиск прыжка будет соответствовать прыжкам , прыжкам , прыжкам и даже прыжкам .

  • Поиск по запросу johnny walker будет соответствовать Johnnie Walker, а johnnie depp должен соответствовать Johnny Depp.

  • Новости охоты на лис должны возвращать истории Foxs News об охоте, между тем новости об охоте на лис должны возвращать истории об охоте на лис.

Чтобы упростить такие запросы в полнотекстовом домене, Elasticsearch сначала анализирует документ, а затем создает инверсию на основе результатов.

показатель .

Когда использовать токенизатор:

1. Когда вы запрашиваете полнотекстовый домен, тот же анализатор применяется к строке запроса для получения правильного списка условий поиска.

2. Когда вы запрашиваете поле точного значения, строка запроса не анализируется, но выполняется поиск точного значения, которое вы укажете.

3. Поле даты содержит точное значение: отдельная запись «2014-09-15».

4. Поле _all является полнотекстовым, поэтому процесс токенизации преобразует дату в три записи: «2014», «09» и «15».

Когда мы запрашиваем 2014 в поле _all, он соответствует всем 12 твитам, потому что все они содержат `2014:

Самый важный запрос: запрос match_all

Запрос match_all просто сопоставляет все документы. Если метод запроса не указан, это запрос по умолчанию.

соответствующий запрос

Независимо от того, выполняете ли вы полнотекстовый поиск или точный запрос по какому-либо полю, запрос на соответствие — это стандартный доступный вам запрос.

Если вы используете запрос соответствия для полнотекстового поля, он будет анализировать строку запроса с помощью правильного синтаксического анализатора перед выполнением запроса:

Если вы используете запрос соответствия для полнотекстового поля, он будет анализировать строку запроса с помощью правильного синтаксического анализатора перед выполнением запроса:

{ "match": { "tweet": "About Search" }}

Если вы используете его в поле с точным значением, например числом, датой, логическим значением или строковым полем not_analyzed, тогда оно будет точно соответствовать заданному значению:

{ "match": { "age":    26           }}

{ "match": { "date":   "2014-09-01" }}

{ "match": { "public": true         }}

{ "match": { "tag":    "full_text"  }}

Запрос Multi_match

Запрос multi_match может выполнять один и тот же запрос соответствия для нескольких полей.

{    "multi_match": {        "query": "full text search",        "fields": [            "title",            "body"        ]    }

}

Запрос диапазона

Запрос диапазона находит те числа или времена, которые попадают в указанный диапазон:

{

        "range": {

        "age": {

        "gte":  20,

        "lt":   30

        }

    }

}

Допустимые операторы:

gt больше, чем

gte больше или равно

это меньше, чем

lte меньше или равно

термин запрос

запросы терминов используются для точного сопоставления значений, которые могут быть числами, временем, логическими значениями или непроанализированными строками.

{ "term": { "age":    26           }}

{ "term": { "date":   "2014-09-01" }}

{ "term": { "public": true         }}

{ "term": { "tag":    "full_text"  }}

Условия запроса

Запрос терминов аналогичен запросу терминов, но позволяет указать несколько значений для сопоставления. Если поле содержит любое из указанных значений, то документ удовлетворяет условию:

{ "terms": { "tag": [ "search", "full_text", "nosql" ] }}

Как и запрос терминов, запрос терминов не анализирует входной текст, а ищет значения, которые точно совпадают (включая различия в регистре, ударении, пробелах и т. д.).

Существует запрос и отсутствующий запрос

Запрос существования и запрос отсутствия используются для поиска документов, которые имеют значение (существует) или не имеют значения (отсутствует) в указанном поле. По сути, это характерно для IS_NULL (отсутствует) и NOT IS_NULL (существует) в SQL:

{    "exists": {        "field": "title"    }

}

Объединить несколько запросов

Boolquery

Такой запрос объединяет несколько запросов в логический запрос, который хочет сам пользователь, и получает следующие параметры:

Обязательный документ должен соответствовать этим условиям, чтобы быть включенным.

Для включения документы must_not не должны соответствовать этим условиям.

должен увеличить _score, если выполняется какое-либо из этих утверждений, в противном случае не имеет никакого эффекта Они в основном используются для исправления оценки релевантности каждого документа.

фильтр должен соответствовать, но он делает это в режиме фильтрации без оценки.Эти операторы не влияют на оценку, просто исключают или включают документы на основе критериев фильтрации.

{    "bool": {        "must": {            "match": {                "title": "how to make millions"            }        },        "must_not": {            "match": {                "tag": "spam"            }        },        "should": [            {                "match": {                    "tag": "starred"                }            },            {                "range": {                    "date": {                        "gte": "2014-01-01"                    }                }            }        ]    }

}

Если оператора must нет, то хотя бы один из них должен совпадать. Однако, если имеется хотя бы один оператор must, соответствие оператора must не требуется.

Фильтрация: добавить запрос с фильтром

Если мы не хотим влиять на оценку из-за времени документа, мы можем переписать предыдущий пример с оператором фильтра:

{    "bool": {        "must": {            "match": {                "title": "how to make millions"            }        },        "must_not": {            "match": {                "tag": "spam"            }        },        "should": [            {                "match": {                    "tag": "starred"                }            }        ],        "filter": {            "range": {                "date": {                    "gte": "2014-01-01"                }            }        }    }

}

Переместив запрос диапазона в оператор фильтра, мы превратили его в запрос без оценки, который больше не будет влиять на ранжирование релевантности документов. Поскольку теперь это запрос без оценки, для повышения производительности можно использовать различные оптимизации, эффективные для запросов с фильтрами.

Все запросы могут извлечь уроки из этого подхода. Переместите запрос в оператор фильтра логического запроса, чтобы он автоматически превратился в неоценивающий фильтр.

Сам логический запрос также можно использовать как запрос без оценки, если вам нужно отфильтровать документы по нескольким различным критериям. Просто поместите его в оператор фильтра и постройте внутри логическую логику:

{    "bool": {        "must": {            "match": {                "title": "how to make millions"            }        },        "must_not": {            "match": {                "tag": "spam"            }        },        "should": [            {                "match": {                    "tag": "starred"                }            }        ],        "filter": {            "bool": {                "must": [                    {                        "range": {                            "date": {                                "gte": "2014-01-01"                            }                        }                    },                    {                        "range": {                            "price": {                                "lte": 29.99                            }                        }                    }                ],                "must_not": [                    {                        "term": {                            "category": "ebooks"                        }                    }                ]            }        }    }

}

Запрос Constant_score

Он применяет инвариантную постоянную оценку ко всем соответствующим документам. Он часто используется, когда вам нужно только выполнить фильтр и никаких других запросов (например, запросов на оценку).

Его можно использовать для замены логического запроса только оператором фильтра. С точки зрения производительности он точно такой же, но имеет большое значение для улучшения краткости и ясности запросов.

{    "constant_score": {        "filter": {            "term": {                "category": "ebooks"            }        }    }

}

Термин запрос помещается в константу_оценки и превращается в фильтр без подсчета очков. Этот подход можно использовать для замены логических запросов только оператором фильтра.

Разница между ES и solr:

http://blog.csdn.net/AlvinNoending/article/details/45534177

https://www.cnblogs.com/huajiezh/p/6033656.html