ElasticSearch的scroll接口搜索示例


=Start=

缘由:

之前整理过一篇「ElasticSearch的搜索API学习整理」的文章,但里面介绍的主要是一些搜索语法、限制条件,并没有实际搞定最终匹配数量超过10000的数据获取办法,其实方法也很简单——使用scroll接口分批次取,这里简单记录一下,方便以后参考。

正文:

参考解答:
# 方法一:HTTP请求 scroll 接口

scroll是先做一次初始化搜索把所有符合搜索条件的结果缓存起来生成一个快照,然后持续地、批量地从快照里拉取数据直到没有数据剩下。而这时对索引数据的插入、删除、更新都不会影响遍历结果,因此scroll并不适合用来做实时搜索。

需要先执行一个初始化搜索请求,传递一个scroll参数来告诉 Elasticsearch缓存应该持续多长时间,在缓存持续时间内初始化搜索请求后对索引的修改不会反应到快照中。每次搜索请求后都会返回一个scrollId,是一个 64 位的字符串编码,后续会使用此scrollId来获取数据。scroll时间指的是本次数据处理所需要的时间,如果超过此时间,继续使用该scrollId搜索数据则会报错。

#!/usr/bin/env python
# coding=utf-8

import sys, time
import json
import requests

def main():
    elastic_url = 'http://localhost:9200/index_name/_search?scroll=2m'
    payload = {
        "size": 10,
        "query": {
            "bool" : {
                "must": {
                    "query_string": {
                       "query": "spend_time:>=1000",
                    }
                },
                "filter": {
                    "range" : {
                        "es_timestamp" : {
                            "gte": "2018/08/30 00:00:32 +0800",
                            "lte": "2018/08/31 00:00:32 +0800",
                        }
                    }
                }
            }
        }
    }

    r = requests.post(elastic_url, data=json.dumps(payload))
    resp_json = r.json()
    hits = resp_json['hits']['hits']
    _scroll_id = resp_json['_scroll_id']

    # 注意,这里的URL和上面的不一样,并没有 index_name 信息,对于新手来说千万注意!
    # scroll_api_url = 'http://localhost:9200/_search/scroll'
    scroll_api_url = 'http://localhost:9200/_search/scroll?filter_path=_shards,_scroll_id,hits.total,hits.hits._source'
    
    while hits:
        print "hits: {}".format(len(hits))
        print "_scroll_id: {}".format(_scroll_id)

        scroll_payload = {
            'scroll': '2m',
            'scroll_id': _scroll_id
        }
        scroll_r = requests.post(scroll_api_url, data=json.dumps(scroll_payload))
        resp_json = scroll_r.json()
        # print resp_json
        hits = resp_json['hits']['hits']
        _scroll_id = resp_json['_scroll_id']


if __name__ == '__main__':
    time_start = time.time()
    try:
        main()
    except KeyboardInterrupt:
        print 'Killed by user'
        sys.exit(0)
    print "Spend {0} seconds.\n".format(time.time() - time_start)

 

# 方法二:使用官方提供的库

 

参考链接:

=END=


《 “ElasticSearch的scroll接口搜索示例” 》 有 7 条评论

  1. Set up minimal security for Elasticsearch
    为 Elasticsearch 设置最小的安全性
    https://www.elastic.co/guide/en/elasticsearch/reference/current/security-minimal-setup.html
    `
    如果您正在运行一个现有的、不安全的集群,并且希望启用 Elasticsearch 安全特性,则只需要完成以下步骤。

    在 Elasticsearch 8.0 及以后版本中,首次启动 Elasticsearch 时,会自动开启安全功能。

    如果您运行的是已禁用安全功能的现有Elasticsearch集群,则可以手动启用Elasticsearch安全功能,然后为内置用户创建密码。您可以稍后添加更多用户,但是使用内置用户简化了为集群启用安全性的过程。

    最低安全性场景对于生产模式集群是不够的。如果您的集群有多个节点,则必须启用最低安全性,然后在节点之间配置传输层安全性(TLS)。

    1. 开启Elasticsearch安全特性

    启用Elasticsearch安全特性提供了基本的身份验证,以便您可以使用用户名和密码身份验证运行本地集群。

    $ vim $ES_PATH_CONF/elasticsearch.yml
    xpack.security.enabled: true

    2. 设置内置用户的密码
    ./bin/elasticsearch
    ./bin/elasticsearch-reset-password -u elastic
    ./bin/elasticsearch-reset-password -i -u elastic
    ./bin/elasticsearch-reset-password -u kibana_system

    3. 配置Kibana使用密码连接Elasticsearch
    $ vim KBN_PATH_CONF/kibana.yml
    elasticsearch.username: “kibana_system”

    恭喜你!您为本地集群启用了密码保护,以防止未经授权的访问。您可以使用弹性用户安全登录Kibana,并创建其他用户和角色。如果您运行的是单节点集群,那么您可以停在这里。

    如果您的集群有多个节点,那么您必须在节点之间配置传输层安全性(TLS)。如果不启用TLS,生产模式集群将不会启动。

    为Elastic Stack设置基本安全性,以保护集群中节点之间的所有内部通信。
    `

  2. How to set a password for Elasticsearch ?
    https://medium.com/@kaangorur/elasticsearch-basic-authentication-for-cluster-en-3728ba7acf8a
    `
    $ ./bin/elasticsearch-setup-passwords interactive

    $ vim elasticsearch.yml

    # Enable security features
    xpack.security.enabled: true

    ==
    什么是集群?

    Elasticsearch中的术语“集群”指的是由Elasticsearch节点连接形成的结构。换句话说,多个Elasticsearch节点聚集在一起形成单个逻辑单元的结构称为“集群”。

    Elasticsearch集群代表了存储和处理数据的数据集。每个节点持有数据的一部分,并与集群中的其他节点合作。这提供了数据备份、高可用性、可伸缩性和快速数据处理等优点。

    通常在集群中安装一台主机,然后安装n个节点并将其合并到主集群中。

    在主机上定义Elasticsearch加密过程,在主机上生成证书并导入到其他节点,以便集群中的所有机器可以相互通信。
    `

    Elastic Docs ›Elasticsearch Guide [8.13] ›Command line tools
    https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-passwords.html
    `
    elasticsearch-setup-passwords #Deprecated in 8.0.

    The elasticsearch-setup-passwords tool is deprecated and will be removed in a future release. To manually reset the password for the built-in users (including the elastic user), use the elasticsearch-reset-password tool, the Elasticsearch change password API, or the User Management features in Kibana.

    elasticsearch-setup-passwords 工具已弃用,并将在将来的版本中删除。对于内置用户(包括 elastic 用户),可以使用 elasticsearch-reset-password 工具、Elasticsearch修改密码API 或 Kibana的用户管理功能手动重置密码。
    `

  3. 启动 Elastic 技术栈并自动进行安全配置
    Start the Elastic Stack with security enabled automatically
    https://www.elastic.co/guide/en/elasticsearch/reference/current/configuring-stack-security.html
    `
    首次启动 Elasticsearch 时,会自动进行如下安全配置:

    1. TLS的证书和密钥是为传输层和HTTP层生成的。
    2. 将TLS配置设置写入 elasticsearch.yml
    3. 为 elastic 用户生成密码。
    4. 为 Kibana 生成一个注册令牌。

    然后,您可以启动Kibana并输入注册令牌,该令牌的有效期为30分钟。这个令牌自动应用Elasticsearch集群的安全设置,使用内置的kibana服务帐户对Elasticsearch进行身份验证,并将安全配置写入kibana.yml。

    在某些情况下,无法自动配置安全性,因为节点启动进程检测到节点已经是集群的一部分,或者已经配置或显式禁用了安全性。
    `

  4. Elasticsearch security principles
    Elasticsearch 的安全原则
    https://www.elastic.co/guide/en/elasticsearch/reference/current/es-security-principles.html
    `
    运行Elasticsearch并启用安全功能 (Run Elasticsearch with security enabled)

    使用专用的非root用户运行Elasticsearch (Run Elasticsearch with a dedicated non-root user)

    保护Elasticsearch免受公共互联网流量的影响 (Protect Elasticsearch from public internet traffic)

    实现基于角色的访问控制(Implement role based access control)
    `

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注