5.0 compatibility

This commit is contained in:
Honza Král
2016-03-22 21:04:07 +01:00
parent b10ae7c891
commit 6e94bf76ad
14 changed files with 187 additions and 155 deletions
+5
View File
@@ -3,6 +3,11 @@
Changelog
=========
5.0.0 (dev)
-----------
Version compatible with elasticsearch 5.0
2.3.0 (2016-02-29)
------------------
+7 -1
View File
@@ -28,6 +28,9 @@ Compatibility
The library is compatible with all Elasticsearch versions since ``0.90.x`` but you
**have to use a matching major version**:
For **Elasticsearch 5.0** and later, use the major version 5 (``5.x.y``) of the
library.
For **Elasticsearch 2.0** and later, use the major version 2 (``2.x.y``) of the
library.
@@ -40,6 +43,9 @@ library.
The recommended way to set your requirements in your `setup.py` or
`requirements.txt` is::
# Elasticsearch 5.x
elasticsearch>=5.0.0,<6.0.0
# Elasticsearch 2.x
elasticsearch>=2.0.0,<3.0.0
@@ -49,7 +55,7 @@ The recommended way to set your requirements in your `setup.py` or
# Elasticsearch 0.90.x
elasticsearch<1.0.0
The development is happening on ``master`` and ``1.x`` branches, respectively.
The development is happening on ``master`` and ``2.x`` branches respectively.
Installation
------------
+3 -3
View File
@@ -50,11 +50,11 @@ copyright = u'2013, Honza Král'
# built documents.
#
import elasticsearch
# The short X.Y version.
version = elasticsearch.__versionstr__
version = '5.0.0'
# The full version, including alpha/beta/rc tags.
release = version
release = '5.0.0-dev'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
+1 -1
View File
@@ -1,6 +1,6 @@
from __future__ import absolute_import
VERSION = (2, 3, 0)
VERSION = (5, 0, 0, 'dev')
__version__ = VERSION
__versionstr__ = '.'.join(map(str, VERSION))
+27 -23
View File
@@ -6,10 +6,12 @@ from ..transport import Transport
from ..exceptions import TransportError
from ..compat import string_types, urlparse
from .indices import IndicesClient
from .ingest import IngestClient
from .cluster import ClusterClient
from .cat import CatClient
from .nodes import NodesClient
from .snapshot import SnapshotClient
from .tasks import TasksClient
from .utils import query_params, _make_path, SKIP_IN_PATH
logger = logging.getLogger('elasticsearch')
@@ -64,13 +66,15 @@ class Elasticsearch(object):
Elasticsearch low-level client. Provides a straightforward mapping from
Python to ES REST endpoints.
The instance has attributes ``cat``, ``cluster``, ``indices``, ``nodes``
and ``snapshot`` that provide access to instances of
The instance has attributes ``cat``, ``cluster``, ``indices``, ``ingest``,
``nodes``, ``snapshot`` and ``tasks`` that provide access to instances of
:class:`~elasticsearch.client.CatClient`,
:class:`~elasticsearch.client.ClusterClient`,
:class:`~elasticsearch.client.IndicesClient`,
:class:`~elasticsearch.client.NodesClient` and
:class:`~elasticsearch.client.SnapshotClient` respectively. This is the
:class:`~elasticsearch.client.IngestClient`,
:class:`~elasticsearch.client.NodesClient`,
:class:`~elasticsearch.client.SnapshotClient` and
:class:`~elasticsearch.client.TasksClient` respectively. This is the
preferred (and only supported) way to get access to those classes and their
methods.
@@ -170,10 +174,12 @@ class Elasticsearch(object):
# namespaced clients for compatibility with API names
# use weakref to make GC's work a little easier
self.indices = IndicesClient(weakref.proxy(self))
self.ingest = IngestClient(weakref.proxy(self))
self.cluster = ClusterClient(weakref.proxy(self))
self.cat = CatClient(weakref.proxy(self))
self.nodes = NodesClient(weakref.proxy(self))
self.snapshot = SnapshotClient(weakref.proxy(self))
self.tasks = TasksClient(weakref.proxy(self))
def __repr__(self):
try:
@@ -214,7 +220,7 @@ class Elasticsearch(object):
"""
return self.transport.perform_request('GET', '/', params=params)
@query_params('consistency', 'parent', 'refresh', 'routing',
@query_params('consistency', 'parent', 'pipeline', 'refresh', 'routing',
'timeout', 'timestamp', 'ttl', 'version', 'version_type')
def create(self, index, doc_type, body, id=None, params=None):
"""
@@ -242,8 +248,8 @@ class Elasticsearch(object):
"""
return self.index(index, doc_type, body, id=id, params=params, op_type='create')
@query_params('consistency', 'op_type', 'parent', 'refresh', 'routing',
'timeout', 'timestamp', 'ttl', 'version', 'version_type')
@query_params('consistency', 'op_type', 'parent', 'pipeline', 'refresh',
'routing', 'timeout', 'timestamp', 'ttl', 'version', 'version_type')
def index(self, index, doc_type, body, id=None, params=None):
"""
Adds or updates a typed JSON document in a specific index, making it searchable.
@@ -258,6 +264,7 @@ class Elasticsearch(object):
:arg op_type: Explicit operation type, default 'index', valid choices
are: 'index', 'create'
:arg parent: ID of the parent document
:arg pipeline: The pipeline id to preprocess incoming documents with
:arg refresh: Refresh the index after performing the operation
:arg routing: Specific routing value
:arg timeout: Explicit operation timeout
@@ -295,8 +302,8 @@ class Elasticsearch(object):
for param in (index, doc_type, id):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
return self.transport.perform_request('HEAD', _make_path(index, doc_type,
id), params=params)
return self.transport.perform_request('HEAD', _make_path(index,
doc_type, id), params=params)
@query_params('_source', '_source_exclude', '_source_include', 'fields',
'parent', 'preference', 'realtime', 'refresh', 'routing', 'version',
@@ -402,8 +409,8 @@ class Elasticsearch(object):
return self.transport.perform_request('GET', _make_path(index,
doc_type, '_mget'), params=params, body=body)
@query_params('consistency', 'detect_noop', 'fields', 'lang', 'parent',
'refresh', 'retry_on_conflict', 'routing', 'script', 'script_id',
@query_params('consistency', 'fields', 'lang', 'parent', 'refresh',
'retry_on_conflict', 'routing', 'script', 'script_id',
'scripted_upsert', 'timeout', 'timestamp', 'ttl', 'version',
'version_type')
def update(self, index, doc_type, id, body=None, params=None):
@@ -417,9 +424,6 @@ class Elasticsearch(object):
:arg body: The request definition using either `script` or partial `doc`
:arg consistency: Explicit write consistency setting for the operation,
valid choices are: 'one', 'quorum', 'all'
:arg detect_noop: Specifying as true will cause Elasticsearch to check
if there are changes and, if there aren't, turn the update request
into a noop.
:arg fields: A comma-separated list of fields to return in the response
:arg lang: The script language (default: groovy)
:arg parent: ID of the parent document. Is is only used for routing and
@@ -504,7 +508,7 @@ class Elasticsearch(object):
:arg scroll: Specify how long a consistent view of the index should be
maintained for scrolled search
:arg search_type: Search operation type, valid choices are:
'query_then_fetch', 'dfs_query_then_fetch', 'count', 'scan'
'query_then_fetch', 'dfs_query_then_fetch'
:arg size: Number of hits to return (default: 10)
:arg sort: A comma-separated list of <field>:<direction> pairs
:arg stats: Specific 'tag' of the request for logging and statistical
@@ -591,7 +595,7 @@ class Elasticsearch(object):
maintained for scrolled search
:arg search_type: Search operation type, valid choices are:
'query_then_fetch', 'query_and_fetch', 'dfs_query_then_fetch',
'dfs_query_and_fetch', 'count', 'scan'
'dfs_query_and_fetch'
"""
return self.transport.perform_request('GET', _make_path(index,
doc_type, '_search', 'template'), params=params, body=body)
@@ -746,7 +750,8 @@ class Elasticsearch(object):
return self.transport.perform_request('GET', _make_path(index,
doc_type, '_count'), params=params, body=body)
@query_params('consistency', 'fields', 'refresh', 'routing', 'timeout')
@query_params('consistency', 'fields', 'pipeline', 'refresh', 'routing',
'timeout')
def bulk(self, body, index=None, doc_type=None, params=None):
"""
Perform many index/delete operations in a single API call.
@@ -763,6 +768,7 @@ class Elasticsearch(object):
valid choices are: 'one', 'quorum', 'all'
:arg fields: Default comma-separated list of fields to return in the
response for updates
:arg pipeline: The pipeline id to preprocess incoming documents with
:arg refresh: Refresh the index after performing the operation
:arg routing: Specific routing value
:arg timeout: Explicit operation timeout
@@ -785,7 +791,7 @@ class Elasticsearch(object):
default
:arg search_type: Search operation type, valid choices are:
'query_then_fetch', 'query_and_fetch', 'dfs_query_then_fetch',
'dfs_query_and_fetch', 'count', 'scan'
'dfs_query_and_fetch'
"""
if body in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'body'.")
@@ -941,9 +947,9 @@ class Elasticsearch(object):
return self.transport.perform_request('GET', _make_path(index,
doc_type, id, '_percolate', 'count'), params=params, body=body)
@query_params('dfs', 'field_statistics', 'fields', 'offsets', 'parent',
'payloads', 'positions', 'preference', 'realtime', 'routing',
'term_statistics', 'version', 'version_type')
@query_params('field_statistics', 'fields', 'offsets', 'parent', 'payloads',
'positions', 'preference', 'realtime', 'routing', 'term_statistics',
'version', 'version_type')
def termvectors(self, index, doc_type, id=None, body=None, params=None):
"""
Returns information and statistics on terms in the fields of a
@@ -959,8 +965,6 @@ class Elasticsearch(object):
be supplied.
:arg body: Define parameters and or supply a document to get termvectors
for. See documentation.
:arg dfs: Specifies if distributed frequencies should be returned
instead shard frequencies., default False
:arg field_statistics: Specifies if document count, sum of document
frequencies and sum of total term frequencies should be returned.,
default True
+3 -1
View File
@@ -311,7 +311,7 @@ class CatClient(NamespacedClient):
return self.transport.perform_request('GET', '/_cat/repositories',
params=params)
@query_params('h', 'help', 'master_timeout', 'v')
@query_params('h', 'help', 'ignore_unavailable', 'master_timeout', 'v')
def snapshots(self, repository=None, params=None):
"""
`<http://www.elastic.co/guide/en/elasticsearch/reference/current/cat-snapshots.html>`_
@@ -320,6 +320,8 @@ class CatClient(NamespacedClient):
information
:arg h: Comma-separated list of column names to display
:arg help: Return help information, default False
:arg ignore_unavailable: Set to true to ignore unavailable snapshots,
default False
:arg master_timeout: Explicit operation timeout for connection to master
node
:arg v: Verbose mode. Display column headers, default False
+4 -1
View File
@@ -115,13 +115,16 @@ class ClusterClient(NamespacedClient):
return self.transport.perform_request('POST', '/_cluster/reroute',
params=params, body=body)
@query_params('flat_settings', 'master_timeout', 'timeout')
@query_params('flat_settings', 'include_defaults', 'master_timeout',
'timeout')
def get_settings(self, params=None):
"""
Get cluster settings.
`<http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-update-settings.html>`_
:arg flat_settings: Return settings in flat format (default: false)
:arg include_defaults: Whether to return all default clusters setting.,
default False
:arg master_timeout: Explicit operation timeout for connection to master
node
:arg timeout: Explicit operation timeout
+15 -120
View File
@@ -1,8 +1,8 @@
from .utils import NamespacedClient, query_params, _make_path, SKIP_IN_PATH
class IndicesClient(NamespacedClient):
@query_params('analyzer', 'char_filters', 'field', 'filters', 'format',
'prefer_local', 'text', 'tokenizer')
@query_params('analyzer', 'attributes', 'char_filters', 'explain', 'field',
'filters', 'format', 'prefer_local', 'text', 'tokenizer')
def analyze(self, index=None, body=None, params=None):
"""
Perform the analysis process on a text and return the tokens breakdown of the text.
@@ -11,8 +11,12 @@ class IndicesClient(NamespacedClient):
:arg index: The name of the index to scope the operation
:arg body: The text on which the analysis should be performed
:arg analyzer: The name of the analyzer to use
:arg attributes: A comma-separated list of token attributes to output,
this parameter works only with `explain=true`
:arg char_filters: A comma-separated list of character filters to use
for the analysis
:arg explain: With `true`, outputs more advanced details. (default:
false)
:arg field: Use the analyzer configured for this field (instead of
passing the analyzer name)
:arg filters: A comma-separated list of filters to use for the analysis
@@ -513,7 +517,7 @@ class IndicesClient(NamespacedClient):
_make_path('_template', name), params=params)
@query_params('allow_no_indices', 'expand_wildcards', 'flat_settings',
'human', 'ignore_unavailable', 'local')
'human', 'ignore_unavailable', 'include_defaults', 'local')
def get_settings(self, index=None, name=None, params=None):
"""
Retrieve settings for one or more (or all) indices.
@@ -533,6 +537,8 @@ class IndicesClient(NamespacedClient):
readable format., default False
:arg ignore_unavailable: Whether specified concrete indices should be
ignored when unavailable (missing or closed)
:arg include_defaults: Whether to return all default setting for each of
the indices., default False
:arg local: Return local information, do not retrieve the state from
master node (default: false)
"""
@@ -540,7 +546,7 @@ class IndicesClient(NamespacedClient):
'_settings', name), params=params)
@query_params('allow_no_indices', 'expand_wildcards', 'flat_settings',
'ignore_unavailable', 'master_timeout')
'ignore_unavailable', 'master_timeout', 'preserve_existing')
def put_settings(self, body, index=None, params=None):
"""
Change specific index level settings in real time.
@@ -559,96 +565,15 @@ class IndicesClient(NamespacedClient):
:arg ignore_unavailable: Whether specified concrete indices should be
ignored when unavailable (missing or closed)
:arg master_timeout: Specify timeout for connection to master
:arg preserve_existing: Whether to update existing settings. If set to
`true` existing settings on an index remain unchanged, the default
is `false`
"""
if body in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'body'.")
return self.transport.perform_request('PUT', _make_path(index,
'_settings'), params=params, body=body)
@query_params('allow_no_indices', 'expand_wildcards', 'ignore_unavailable',
'master_timeout', 'request_cache')
def put_warmer(self, name, body, index=None, doc_type=None, params=None):
"""
Create an index warmer to run registered search requests to warm up the
index before it is available for search.
`<http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-warmers.html>`_
:arg name: The name of the warmer
:arg body: The search request definition for the warmer (query, filters,
facets, sorting, etc)
:arg index: A comma-separated list of index names to register the warmer
for; use `_all` or omit to perform the operation on all indices
:arg doc_type: A comma-separated list of document types to register the
warmer for; leave empty to perform the operation on all types
:arg allow_no_indices: Whether to ignore if a wildcard indices
expression resolves into no concrete indices in the search request
to warm. (This includes `_all` string or when no indices have been
specified)
:arg expand_wildcards: Whether to expand wildcard expression to concrete
indices that are open, closed or both, in the search request to
warm., default 'open', valid choices are: 'open', 'closed', 'none',
'all'
:arg ignore_unavailable: Whether specified concrete indices should be
ignored when unavailable (missing or closed) in the search request
to warm
:arg master_timeout: Specify timeout for connection to master
:arg request_cache: Specify whether the request to be warmed should use
the request cache, defaults to index level setting
"""
for param in (name, body):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
return self.transport.perform_request('PUT', _make_path(index,
doc_type, '_warmer', name), params=params, body=body)
@query_params('allow_no_indices', 'expand_wildcards', 'ignore_unavailable',
'local')
def get_warmer(self, index=None, doc_type=None, name=None, params=None):
"""
Retreieve an index warmer.
`<http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-warmers.html>`_
:arg index: A comma-separated list of index names to restrict the
operation; use `_all` to perform the operation on all indices
:arg doc_type: A comma-separated list of document types to restrict the
operation; leave empty to perform the operation on all types
:arg name: The name of the warmer (supports wildcards); leave empty to
get all warmers
:arg allow_no_indices: Whether to ignore if a wildcard indices
expression resolves into no concrete indices. (This includes `_all`
string or when no indices have been specified)
:arg expand_wildcards: Whether to expand wildcard expression to concrete
indices that are open, closed or both., default 'open', valid
choices are: 'open', 'closed', 'none', 'all'
:arg ignore_unavailable: Whether specified concrete indices should be
ignored when unavailable (missing or closed)
:arg local: Return local information, do not retrieve the state from
master node (default: false)
"""
return self.transport.perform_request('GET', _make_path(index,
doc_type, '_warmer', name), params=params)
@query_params('master_timeout')
def delete_warmer(self, index, name, params=None):
"""
Delete an index warmer.
`<http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-warmers.html>`_
:arg index: A comma-separated list of index names to delete warmers from
(supports wildcards); use `_all` to perform the operation on all
indices.
:arg name: A comma-separated list of warmer names to delete (supports
wildcards); use `_all` to delete all warmers in the specified
indices. You must specify a name either in the uri or in the
parameters.
:arg master_timeout: Specify timeout for connection to master
"""
for param in (index, name):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
return self.transport.perform_request('DELETE', _make_path(index,
'_warmer', name), params=params)
@query_params('completion_fields', 'fielddata_fields', 'fields', 'groups',
'human', 'level', 'types')
def stats(self, index=None, metric=None, params=None):
@@ -678,7 +603,7 @@ class IndicesClient(NamespacedClient):
'_stats', metric), params=params)
@query_params('allow_no_indices', 'expand_wildcards', 'human',
'ignore_unavailable', 'operation_threading')
'ignore_unavailable', 'operation_threading', 'verbose')
def segments(self, index=None, params=None):
"""
Provide low level segments information that a Lucene index (shard level) is built with.
@@ -697,41 +622,11 @@ class IndicesClient(NamespacedClient):
:arg ignore_unavailable: Whether specified concrete indices should be
ignored when unavailable (missing or closed)
:arg operation_threading: TODO: ?
:arg verbose: Includes detailed memory usage by Lucene., default False
"""
return self.transport.perform_request('GET', _make_path(index,
'_segments'), params=params)
@query_params('allow_no_indices', 'expand_wildcards', 'flush',
'ignore_unavailable', 'max_num_segments', 'only_expunge_deletes',
'operation_threading', 'wait_for_merge')
def optimize(self, index=None, params=None):
"""
Explicitly optimize one or more indices through an API.
`<http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-optimize.html>`_
:arg index: A comma-separated list of index names; use `_all` or empty
string to perform the operation on all indices
:arg allow_no_indices: Whether to ignore if a wildcard indices
expression resolves into no concrete indices. (This includes `_all`
string or when no indices have been specified)
:arg expand_wildcards: Whether to expand wildcard expression to concrete
indices that are open, closed or both., default 'open', valid
choices are: 'open', 'closed', 'none', 'all'
:arg flush: Specify whether the index should be flushed after performing
the operation (default: true)
:arg ignore_unavailable: Whether specified concrete indices should be
ignored when unavailable (missing or closed)
:arg max_num_segments: The number of segments the index should be merged
into (default: dynamic)
:arg only_expunge_deletes: Specify whether the operation should only
expunge deleted documents
:arg operation_threading: TODO: ?
:arg wait_for_merge: Specify whether the request should block until the
merge process is finished (default: true)
"""
return self.transport.perform_request('POST', _make_path(index,
'_optimize'), params=params)
@query_params('allow_no_indices', 'analyze_wildcard', 'analyzer',
'default_operator', 'df', 'expand_wildcards', 'explain',
'ignore_unavailable', 'lenient', 'lowercase_expanded_terms',
+63
View File
@@ -0,0 +1,63 @@
from .utils import NamespacedClient, query_params, _make_path, SKIP_IN_PATH
class IngestClient(NamespacedClient):
@query_params('master_timeout')
def get_pipeline(self, id, params=None):
"""
`<https://www.elastic.co/guide/en/elasticsearch/plugins/current/ingest.html>`_
:arg id: Comma separated list of pipeline ids. Wildcards supported
:arg master_timeout: Explicit operation timeout for connection to master
node
"""
if id in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'id'.")
return self.transport.perform_request('GET', _make_path('_ingest',
'pipeline', id), params=params)
@query_params('master_timeout', 'timeout')
def put_pipeline(self, id, body, params=None):
"""
`<https://www.elastic.co/guide/en/elasticsearch/plugins/current/ingest.html>`_
:arg id: Pipeline ID
:arg body: The ingest definition
:arg master_timeout: Explicit operation timeout for connection to master
node
:arg timeout: Explicit operation timeout
"""
for param in (id, body):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
return self.transport.perform_request('PUT', _make_path('_ingest',
'pipeline', id), params=params, body=body)
@query_params('master_timeout', 'timeout')
def delete_pipeline(self, id, params=None):
"""
`<https://www.elastic.co/guide/en/elasticsearch/plugins/current/ingest.html>`_
:arg id: Pipeline ID
:arg master_timeout: Explicit operation timeout for connection to master
node
:arg timeout: Explicit operation timeout
"""
if id in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'id'.")
return self.transport.perform_request('DELETE', _make_path('_ingest',
'pipeline', id), params=params)
@query_params('verbose')
def simulate(self, body, id=None, params=None):
"""
`<https://www.elastic.co/guide/en/elasticsearch/plugins/current/ingest.html>`_
:arg body: The simulate definition
:arg id: Pipeline ID
:arg verbose: Verbose mode. Display data output for each processor in
executed pipeline, default False
"""
if body in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'body'.")
return self.transport.perform_request('GET', _make_path('_ingest',
'pipeline', id, '_simulate'), params=params, body=body)
+45
View File
@@ -0,0 +1,45 @@
from .utils import NamespacedClient, query_params, _make_path, SKIP_IN_PATH
class TasksClient(NamespacedClient):
@query_params('actions', 'detailed', 'node_id', 'parent_node',
'parent_task', 'wait_for_completion')
def list(self, task_id=None, params=None):
"""
`<http://www.elastic.co/guide/en/elasticsearch/reference/current/tasks-list.html>`_
:arg task_id: Return the task with specified id
:arg actions: A comma-separated list of actions that should be returned.
Leave empty to return all.
:arg detailed: Return detailed task information (default: false)
:arg node_id: A comma-separated list of node IDs or names to limit the
returned information; use `_local` to return information from the
node you're connecting to, leave empty to get information from all
nodes
:arg parent_node: Return tasks with specified parent node.
:arg parent_task: Return tasks with specified parent task id. Set to -1
to return all.
:arg wait_for_completion: Wait for the matching tasks to complete
(default: false)
"""
return self.transport.perform_request('GET', _make_path('_tasks',
task_id), params=params)
@query_params('actions', 'node_id', 'parent_node', 'parent_task')
def cancel(self, task_id=None, params=None):
"""
`<http://www.elastic.co/guide/en/elasticsearch/reference/current/tasks-cancel.html>`_
:arg task_id: Cancel the task with specified id
:arg actions: A comma-separated list of actions that should be
cancelled. Leave empty to cancel all.
:arg node_id: A comma-separated list of node IDs or names to limit the
returned information; use `_local` to return information from the
node you're connecting to, leave empty to get information from all
nodes
:arg parent_node: Cancel tasks with specified parent node.
:arg parent_task: Cancel tasks with specified parent task id. Set to -1
to cancel all.
"""
return self.transport.perform_request('POST', _make_path('_tasks',
task_id, '_cancel'), params=params)
+3 -2
View File
@@ -268,7 +268,8 @@ def scan(client, query=None, scroll='5m', raise_on_error=True, preserve_order=Fa
"""
if not preserve_order:
kwargs['search_type'] = 'scan'
body = query.copy() if query else {}
body["sort"] = "_doc"
# initial search
resp = client.search(body=query, scroll=scroll, **kwargs)
@@ -279,7 +280,7 @@ def scan(client, query=None, scroll='5m', raise_on_error=True, preserve_order=Fa
first_run = True
while True:
# if we didn't set search_type to scan initial search contains data
if preserve_order and first_run:
if first_run:
first_run = False
else:
resp = client.scroll(scroll_id, scroll=scroll)
+1 -1
View File
@@ -4,7 +4,7 @@ from setuptools import setup, find_packages
import sys
import os
VERSION = (2, 3, 0)
VERSION = (5, 0, 0, 'dev')
__version__ = VERSION
__versionstr__ = '.'.join(map(str, VERSION))
@@ -7,6 +7,7 @@ import re
from os import walk, environ
from os.path import exists, join, dirname, pardir
import yaml
from shutil import rmtree
from elasticsearch import TransportError
from elasticsearch.compat import string_types
@@ -48,6 +49,13 @@ class YamlTestCase(ElasticsearchTestCase):
self.last_response = None
self._state = {}
def tearDown(self):
super(YamlTestCase, self).tearDown()
for repo, definition in self.client.snapshot.get_repository(repository='_all').items():
self.client.snapshot.delete_repository(repository=repo)
if definition['type'] == 'fs':
rmtree('/tmp/%s' % definition['settings']['location'])
def _resolve(self, value):
# resolve variables
if isinstance(value, string_types) and value.startswith('$'):
@@ -191,7 +191,7 @@ class TestScan(ElasticsearchTestCase):
bulk.append({"answer": x, "correct": x == 42})
self.client.bulk(bulk, refresh=True)
docs = list(helpers.scan(self.client, index="test_index", doc_type="answers", size=2, query={"sort": ["answer"]}, preserve_order=True))
docs = list(helpers.scan(self.client, index="test_index", doc_type="answers", query={"sort": "answer"}, preserve_order=True))
self.assertEquals(100, len(docs))
self.assertEquals(list(map(str, range(100))), list(d['_id'] for d in docs))
@@ -229,7 +229,7 @@ class TestReindex(ElasticsearchTestCase):
self.assertEquals({"answer": 42, "correct": True}, self.client.get(index="prod_index", doc_type="answers", id=42)['_source'])
def test_reindex_accepts_a_query(self):
helpers.reindex(self.client, "test_index", "prod_index", query={"query": {"filtered": {"filter": {"term": {"_type": "answers"}}}}})
helpers.reindex(self.client, "test_index", "prod_index", query={"query": {"bool": {"filter": {"term": {"_type": "answers"}}}}})
self.client.indices.refresh()
self.assertTrue(self.client.indices.exists("prod_index"))