Querying Elasticsearch from Google App Engine

For example, the following is from Elasticsearchs Search APIs reference: $ curl -XGET 'http://localhost:9200/twitter/tweet/_search?routing=kimchy' -d '{ "query": { "filtered" : { "query" : { "query_string" : { "query" : "some query string here" } }, "filter" : { "term" : { "user" : "kimchy" } } } } } ' With Google App Engine, any HTTP call made with the HTTP GET verb will have the body payload stripped..The call will need to be sent with the HTTP POST verb..import json import requests url = 'http://123.456.789.012:9200/twitter/tweet/_search?routing=kimchy' headers = {'content-type': 'application/json'} payload = { "query": { "filtered" : { "query" : { "query_string" : { "query" : "some query string here" } }, "filter" : { "term" : { "user" : "kimchy" } } } } } resp = requests.post(url, data=json.dumps(payload), headers=headers) But when Elasticsearch receives the search query with the HTTP POST verb it will think its a call to create a record rather than perform a search..The use of _search in the endpoint URL will further confuse matters..The solution I found was to run nginx on the Google Compute Engine Instance running Elasticsearch and convert any HTTP POST calls to HTTP GET in the nginx proxy configuration: server { listen 80; ….various proxy settings ….location ~* / { ….http basic auth settings ….set $allow_method 0; if ($request_method = 'GET') { set $allow_method 1; } if ($request_method = 'POST') { set $allow_method 1; } if ($allow_method = 0) { # HTTP Error 405: Method not allowed # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.6 return 405; break; } proxy_pass http://elasticsearch/$uri$is_args$args; proxy_redirect off; # This will change all acceptable calls to HTTP GET # regardless of their original verb usage: proxy_method GET; } } Now you can send search queries with a body payload using HTTP POST and it will be converted by nginx before being handed off to Elasticsearch.. More details

Leave a Reply