ElasticSearch から特定のインデックスのすべての _id を取得する最速の方法は何ですか? 簡単なクエリを使用して可能ですか?私のインデックスの 1 つには、約 20,000 のドキュメントがあります。
11 に答える
スクロールとスキャンを使用して結果リストを取得することをお勧めします。これにより、elasticsearch が結果をランク付けおよびソートする必要がなくなります。
python lib を使用すると、次のelasticsearch-dsl
方法で実現できます。
from elasticsearch import Elasticsearch
from elasticsearch_dsl import Search
es = Elasticsearch()
s = Search(using=es, index=ES_INDEX, doc_type=DOC_TYPE)
s = s.fields([]) # only get ids, otherwise `fields` takes a list of field names
ids = [h.meta.id for h in s.scan()]
コンソール ログ:
GET http://localhost:9200/my_index/my_doc/_search?search_type=scan&scroll=5m [status:200 request:0.003s]
GET http://localhost:9200/_search/scroll?scroll=5m [status:200 request:0.005s]
GET http://localhost:9200/_search/scroll?scroll=5m [status:200 request:0.005s]
GET http://localhost:9200/_search/scroll?scroll=5m [status:200 request:0.003s]
GET http://localhost:9200/_search/scroll?scroll=5m [status:200 request:0.005s]
...
注:スクロールは、クエリから結果のバッチを取得し、カーソルを一定時間 (1 分、2 分、更新可能) 開いたままにします。scanはソートを無効にします。ヘルパー関数は、scan
安全に反復できる python ジェネレーターを返します。
elasticsearch 5.x の場合、「_source」フィールドを使用できます。
GET /_search
{
"_source": false,
"query" : {
"term" : { "user" : "kimchy" }
}
}
"fields"
廃止されました。(エラー: 「フィールド [fields] はサポートされなくなりました。[stored_fields] を使用して保存されたフィールドを取得するか、フィールドが保存されていない場合は _source フィルタリングを行ってください」)
別のオプション
curl 'http://localhost:9200/index/type/_search?pretty=true&fields='
_index、_type、_id、および _score を返します。
@Robert-Lujo と @Aleck-Landgraf による 2 つの回答について詳しく説明します (権限のある人は、これをコメントに喜んで移動できます): 印刷したくないが、返されたジェネレーターからリスト内のすべてを取得する場合は、次のようになります。私が使う:
from elasticsearch import Elasticsearch,helpers
es = Elasticsearch(hosts=[YOUR_ES_HOST])
a=helpers.scan(es,query={"query":{"match_all": {}}},scroll='1m',index=INDEX_NAME)#like others so far
IDs=[aa['_id'] for aa in a]
Pythonでも実行でき、適切なリストが得られます。
import elasticsearch
es = elasticsearch.Elasticsearch()
res = es.search(
index=your_index,
body={"query": {"match_all": {}}, "size": 30000, "fields": ["_id"]})
ids = [d['_id'] for d in res['hits']['hits']]
@ Aleck-Landgrafの回答に触発されて、私にとっては、標準のelasticsearch python APIで直接スキャン機能を使用して機能しました:
from elasticsearch import Elasticsearch
from elasticsearch.helpers import scan
es = Elasticsearch()
for dobj in scan(es,
query={"query": {"match_all": {}}, "fields" : []},
index="your-index-name", doc_type="your-doc-type"):
print dobj["_id"],
これは機能しています!
def select_ids(self, **kwargs):
"""
:param kwargs:params from modules
:return: array of incidents
"""
index = kwargs.get('index')
if not index:
return None
# print("Params", kwargs)
query = self._build_query(**kwargs)
# print("Query", query)
# get results
results = self._db_client.search(body=query, index=index, stored_fields=[], filter_path="hits.hits._id")
print(results)
ids = [_['_id'] for _ in results['hits']['hits']]
return ids