На днях столкнулся с интересной проблемой. Используя модуль elasticsearch для Python захотел задать поиск в списке индексов. Конкретно хочу искать данные за несколько последних суток. Понятно, что можно использовать range в фильтре запроса, но зачем? Ведь у меня индексы разбиты по дням, достаточно задать список индексов для поиска. Но как его задать правильно в параметрах вызова процедуры из модуля elasticsearch?
Документация здесь: http://elasticsearch-py.readthedocs.io/en/master/index.html. Но в ней написано совсем чуть-чуть. Делать надо так:
from elasticsearch import Elasticsearch es = Elasticsearch() res = es.search(index="test-index", body={"query": {"match_all": {}}})
Ага, это понятно. Но в API эластика можно задать список индексов, в которых искать. Как его задать здесь? Как строку? Типа index="index1,index2,index3"
? А вот и ни фига. И сколько не пялься в «документацию» выяснить это нельзя. Смотрим справочник по API в той же документации. Там написано:
index – A comma-separated list of index names to search; use _all or empty string to perform the operation on all indices.
Хрен поймет что бы это значило.
Ладно. Смотрим исходные коды на гитхабе (https://github.com/elastic/elasticsearch-py) и видим там, что параметры парсятся функцией, которая лежит в /elasticsearch/client/utils.py
def _escape(value): """ Escape a single value of a URL string or a query parameter. If it is a list or tuple, turn it into a comma-separated string first. """ # make sequences into comma-separated stings if isinstance(value, (list, tuple)): value = ','.join(value)
Ну вот теперь понятно. Надо, значит, сунуть туда list или tuple. Теперь, когда я хочу посмотреть события за последние n дней (включая текущий) я делаю так:
dates = [] for i in xrange(0,n+1): dates.append((today - timedelta(days=i)).strftime('%Y.%m.%d')) def getindexes (prefix,dates) : indexes = [] for strdate in dates: indexes.append(prefix + strdate) return indexes ... myquery = {"query":\ {\ "constant_score":{ "filter":{"bool":{"must":{"term":{"log_name":"Security"}},"should":{"terms":{ "event_id":[4727,4728,4729,4730,4754,4756,4757,4758,4764] }}}} }\ },\ "sort":{"@timestamp":{"order":"asc"}},\ "size":"10000"\ } es = Elasticsearch() res = es.search(index=getindexes("winlogbeat-",dates),body=myquery)
Собственно, здесь выбираются события связанные с управлением глобальными и универсальными группами безопасности.
Вот, почему нельзя в доке написать просто и ясно? Почему читать исходники понятнее чем документацию? Это у всех так? Или это у меня что-то с головой?