es查询之helpers.scan

楮星鹏
2023-12-01

##当需求查询es数据库中大量数据时,用_search就不符合应用场景了,建议使用helpers.scan,helpers.scan返回的数据对象时迭代器,很大节省内存空间,而且查询速度要远远大于search;search在利用from、size参数控制返回数据的条数,使用 from and size 的深度分页,size=10&from=10000 是非常低效的,因为 100,000 排序的结果必须从每个分片上取出并重新排序最后返回 10 条。这个过程需要对每个请求页重复,scroll进行数据分页,也可以返回大数据,但是search返回的数据是以list的形式,如果一次需要返回的数据量比较大的话,则会十分耗费内存,而且数据传输速度也会比较慢

from elasticsearch6.helpers import bulk, scan

search_query = {
  "query": { 
    "match_phrase": {
      "domain": {
      "query": "xxxxxxxxxxxx.onion"
      }
    }
  }
}
#scroll='5m'查询一次数据在ES中缓存5分钟再销毁
res = scan(client=es, query=search_query, scroll='5m', index='page', doc_type='_doc', timeout='1m')
cnt = 0
for record in res:
	print(cnt, record["_source"]["url"])
	cnt += 1

还有一种需求场景,想指定某些字段譬如时间倒序查询,并且查询的数据量还比较大那么可以用如下

search_query = {
            "query": {
                "match": {
                    "domain": "xxxxxxxxxxxx.onion"
                    }
                },
            "sort": {
                "crawl_time": {
                    "order": "desc"
                    }
                },
            "size": 20000
        }

res = es.search(index='page', doc_type='_doc',scroll='5m',body=search_query, timeout='10m')
cnt = 0
res_lst = res["hits"]["hits"]
for record in res_lst:
    print(cnt,record["_source"]["url"])
    cnt += 1
 类似资料: