J'utilise elasticsearch-py pour me connecter à ma base de données ES qui contient plus de 3 millions de documents. Je veux retourner tous les documents afin de pouvoir résumer les données et les écrire dans un fichier csv. J'ai pu accomplir cela facilement pour 10 documents (le retour par défaut) en utilisant le code suivant.
es=Elasticsearch("glycerin")
query={"query" : {"match_all" : {}}}
response= es.search(index="_all", doc_type="patent", body=query)
for hit in response["hits"]["hits"]:
print hit
Malheureusement, lorsque j'ai tenté d'implémenter le scan et le défilement afin de pouvoir obtenir tous les documents que j'ai rencontrés, j'ai rencontré des problèmes. Je l'ai essayé de deux manières différentes sans succès.
Méthode 1:
scanResp= es.search(index="_all", doc_type="patent", body=query, search_type="scan", scroll="10m")
scrollId= scanResp['_scroll_id']
response= es.scroll(scroll_id=scrollId, scroll= "10m")
print response
Après scroll/
, Il donne l'ID de défilement puis se termine par ?scroll=10m (Caused by <class 'httplib.BadStatusLine'>: ''))
Méthode 2:
query={"query" : {"match_all" : {}}}
scanResp= helpers.scan(client= es, query=query, scroll= "10m", index="", doc_type="patent", timeout="10m")
for resp in scanResp:
print "Hiya"
Si j'imprime scanResp avant la boucle for, j'obtiens <generator object scan at 0x108723dc0>
. Pour cette raison, je suis relativement certain que je gâche mon défilement d'une manière ou d'une autre, mais je ne sais pas où ni comment le corriger.
Résultats: Encore une fois, après scroll/
, Il donne l'ID de défilement, puis se termine par ?scroll=10m (Caused by <class 'httplib.BadStatusLine'>: ''))
J'ai essayé d'augmenter le nombre maximal de tentatives pour la classe de transport, mais cela n'a pas fait de différence. J'apprécierais beaucoup de savoir comment résoudre ce problème.
Remarque: Mon ES est situé sur un bureau distant sur le même réseau.
La méthode de balayage python génère un appel GET à l'api restante. Il essaie d'envoyer votre scroll_id sur http. Le cas le plus probable ici est que votre scroll_id est trop volumineux pour être envoyé sur http et vous voyez donc cette erreur car elle ne renvoie aucune réponse.
Étant donné que le scroll_id augmente en fonction du nombre de fragments que vous avez, il est préférable d'utiliser un POST et d'envoyer le scroll_id en JSON dans le cadre de la demande. De cette façon, vous contournez la limitation du fait qu'il soit trop grand pour un appel http.
Votre problème a-t-il été résolu?
J'ai une solution simple, vous devez changer le scroll_id
à chaque fois que vous appelez la méthode de défilement comme ci-dessous:
response_tmp = es.scroll(scroll_id=scrollId, scroll= "1m")
scrollId = response_tmp['_scroll_id']