Что такое Elasticsearch прекрасно описано в wikipedia, поэтому здесь это описывать не вижу смысла. Совсем кратко и на свой лад — замечательная штука для поиска по большой базе (десятки тысяч документов, но не миллиарды) с возможностью нечёткого поиска, т.е. в запросе могут быть ошибки, опечатки, пропуски или даже не та раскладка. Замечательность elasticsearch'а в простоте разворачивания, простоте наполнения базы и простоте поиска.
Перед началом работы нужно установить Elasticsearch из пакетов, либо скачать архив и распаковать. После остаётся его запустить (bin/elasticsearch) и можно смотреть в браузере (http://localhost:9200/) как оно работает.
Для "потестить" можно всё делать через браузер/curl.
Добавление документа
$ curl -XPUT 'http://localhost:9200/test/doc/1' -d '{"name":"имя пользователя"}'
здесь
test — индекс
doc — doc_type (можно считать подиндексом индекса)
Поиск
$ curl -XGET 'http://localhost:9200/test/doc/_search?pretty=true' -d '{"query":{"fuzzy":{"name":"плзователь"}}}'
Ну или смотрим в браузере
(pretty=true в запросе просто чтобы в ответ получить json не в одну строку, а нормально отформатированный)
Для работы с Elasticsearch из python'а есть "родной" модуль elasticsearch и сторонний pyelasticsearch. Сторонний появился чуть раньше официального, но с определённой версии работает через официальный (т.е. для работы с ним нужно ставить оба модуля), развивается и дальше и старается быть более pythonic, нежели официальный.
Дальше на правах заметки "только чтобы не забыть" просто выдержки из кода:
Наполнение индекса кучей данных:
# -*- coding: utf-8 -*-
from pyelasticsearch import ElasticSearch, bulk_chunks
import json
# Данных много, данные грузим из файла
with open('file_with_data.json') as datafile:
docs = json.load(datafile)
# На случай проблем с кириллицей перекодируем
for d in docs['documents']:
d['title'] = d['title'].encode("utf-8", "ignore")
d['title_full'] = d['title_full'].encode("utf-8", "ignore")
es = ElasticSearch('http://localhost:9200')
if not len(docs['documents']):
exit
# Clear index
print es.delete_index('documents')
# Данных очень много, поэтому грузить в индекс будем чанками
# и следить за прогрессом в консоли (корявый вариант влоб)
cnt = 0
max_cnt = len(docs['documents']) / 100
print "max = %s" % max_cnt
for actions in bulk_chunks((es.index_op(doc, id=doc.pop('id')) for doc in docs['documents']), docs_per_chunk=100):
cnt += 1
print "%s of %s" % (cnt, max_cnt)
es.bulk(actions, index='documents', doc_type='full')
Поиск по этой куче данных:
# Простой вариант запроса (обычно хватает)
query = 'title:' + string_query
# Запрос с выставлением своих параметров
query = {
'query': {
'multi_match': {
'query': re.sub('"', '', string_query),
'fields': ['title', 'title_full']
}
}
}
# Поиск
res = es.search(query, index='documents', doc_type='full')
print res['hits']
Список найденных документов будет в res['hits']['hits']
В моём случае акция была разовая, поэтому наполнение релизовано довольно грубо. Сперва добавлял документы по-одному через
es.index('documents',
'full',
{'title': 'title master title', 'full_title': 'QA Master'},
id=1)
но на моём объёме данных elasticsearch переставал отвечать на запросы (поиск по проиндексированному) и уходил в постоянный жор одного ядра на 100%, в общем со стороны выглядел вполне залипшим на какой-то своей внутренней проблеме. Минут за десять я так и не дождался нормального поведения и просто переписал заливку данных на чанки по сто документов, добавив хоть какой-то вывод в консоль, чтобы понимать зилип/не_залип.
В документации к модулю есть примеры простого поиска и расширенного с фильтрами. Ну а в документации самого elasticsearch описаны имеющиеся типы поиска, параметры полей индеса (небольшой пример), влияющие на результат, варианты поиска и много всего прочего не менее интересного и полезного для достижения требуемого результата.
Перед началом работы нужно установить Elasticsearch из пакетов, либо скачать архив и распаковать. После остаётся его запустить (bin/elasticsearch) и можно смотреть в браузере (http://localhost:9200/) как оно работает.
Для "потестить" можно всё делать через браузер/curl.
Добавление документа
$ curl -XPUT 'http://localhost:9200/test/doc/1' -d '{"name":"имя пользователя"}'
здесь
test — индекс
doc — doc_type (можно считать подиндексом индекса)
Поиск
$ curl -XGET 'http://localhost:9200/test/doc/_search?pretty=true' -d '{"query":{"fuzzy":{"name":"плзователь"}}}'
Ну или смотрим в браузере
(pretty=true в запросе просто чтобы в ответ получить json не в одну строку, а нормально отформатированный)
Для работы с Elasticsearch из python'а есть "родной" модуль elasticsearch и сторонний pyelasticsearch. Сторонний появился чуть раньше официального, но с определённой версии работает через официальный (т.е. для работы с ним нужно ставить оба модуля), развивается и дальше и старается быть более pythonic, нежели официальный.
Дальше на правах заметки "только чтобы не забыть" просто выдержки из кода:
Наполнение индекса кучей данных:
# -*- coding: utf-8 -*-
from pyelasticsearch import ElasticSearch, bulk_chunks
import json
# Данных много, данные грузим из файла
with open('file_with_data.json') as datafile:
docs = json.load(datafile)
# На случай проблем с кириллицей перекодируем
for d in docs['documents']:
d['title'] = d['title'].encode("utf-8", "ignore")
d['title_full'] = d['title_full'].encode("utf-8", "ignore")
es = ElasticSearch('http://localhost:9200')
if not len(docs['documents']):
exit
# Clear index
print es.delete_index('documents')
# Данных очень много, поэтому грузить в индекс будем чанками
# и следить за прогрессом в консоли (корявый вариант влоб)
cnt = 0
max_cnt = len(docs['documents']) / 100
print "max = %s" % max_cnt
for actions in bulk_chunks((es.index_op(doc, id=doc.pop('id')) for doc in docs['documents']), docs_per_chunk=100):
cnt += 1
print "%s of %s" % (cnt, max_cnt)
es.bulk(actions, index='documents', doc_type='full')
Поиск по этой куче данных:
# Простой вариант запроса (обычно хватает)
query = 'title:' + string_query
# Запрос с выставлением своих параметров
query = {
'query': {
'multi_match': {
'query': re.sub('"', '', string_query),
'fields': ['title', 'title_full']
}
}
}
# Поиск
res = es.search(query, index='documents', doc_type='full')
print res['hits']
Список найденных документов будет в res['hits']['hits']
В моём случае акция была разовая, поэтому наполнение релизовано довольно грубо. Сперва добавлял документы по-одному через
es.index('documents',
'full',
{'title': 'title master title', 'full_title': 'QA Master'},
id=1)
но на моём объёме данных elasticsearch переставал отвечать на запросы (поиск по проиндексированному) и уходил в постоянный жор одного ядра на 100%, в общем со стороны выглядел вполне залипшим на какой-то своей внутренней проблеме. Минут за десять я так и не дождался нормального поведения и просто переписал заливку данных на чанки по сто документов, добавив хоть какой-то вывод в консоль, чтобы понимать зилип/не_залип.
В документации к модулю есть примеры простого поиска и расширенного с фильтрами. Ну а в документации самого elasticsearch описаны имеющиеся типы поиска, параметры полей индеса (небольшой пример), влияющие на результат, варианты поиска и много всего прочего не менее интересного и полезного для достижения требуемого результата.
Комментариев нет:
Отправить комментарий