3

I am using Ajax request for elasticsearch to get search results. Finally, I have found the query which I have to go for. (This is a follow up question to link)

Here is the query in cURL:

[~]$ curl -XGET 'localhost:9200/firebase/_search?pretty' -H 'Content-Type: application/json' -d'
> {"query": {"match": {"song": {"query": "i am in", "operator": "and"}}}}'

Result:

{
  "took" : 286,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.8630463,
    "hits" : [
      {
        "_index" : "firebase",
        "_type" : "song",
        "_id" : "0001",
        "_score" : 0.8630463,
        "_source" : {
          "song" : "i am in california",
          "song_name" : "hello",
          "song_url" : "https://s3.ap-south-1.amazonaws.com/..."
        }
      }
    ]
  }
}

This query gives me result exactly what I need. When I am using the same request with AJAX, it gives me a bad request.

Ajax.js

Case 1:

$(function() {
    $('#message').keyup(function() {    
        var query = {
            "query": {
                "match": {
                    "song": {
                        "query": $("#message").val(),
                        "operator": "and"
                    }
                }
            }
        };

        console.log(JSON.stringify(query));

        $.ajax({
            type: "GET",
            url: "http://localhost:9200/firebase/_search",
            contentType: 'application/json',
            data: query,
            success: searchSuccess,
            dataType: 'json'
        });

    });

});

Result in console:

enter image description here

Case 2: If I convert the 'data' using JSON.stringify, it gives me:enter image description here

Case 3: If I change the query structure as following and use JSON.stringify on 'data':

var query = {
    query: {
        match: {
            song: {
                query: $("#message").val(),
                operator: "and"
            }
        }
    }
};

Result is:

enter image description here

I am not sure what's the issue here, the query is correct because using the same with cURL I am getting correct results in bash. Question is how to correctly create the Ajax request here. Pointers would be appreciated.

Edit: And yes I have enabled CORS in elasticsearch.yml:

http.cors.enabled : true
http.cors.allow-origin : "*"
http.cors.allow-methods : OPTIONS, HEAD, GET, POST, PUT, DELETE
http.cors.allow-headers : X-Requested-With,X-Auth-Token,Content-Type, Content-Length

Edit1: Chrome, Network data underneath so as to provide more information: enter image description here

Edit2: Full error response is below:

{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"request [/firebase/_search] contains unrecognized parameters: [query[match][song][operator]], [query[match][song][query]]"}],"type":"illegal_argument_exception","reason":"request [/firebase/_search] contains unrecognized parameters: [query[match][song][operator]], [query[match][song][query]]"},"status":400}
Manganese
  • 610
  • 5
  • 22
  • instead of localhost you should use server ip address, where elasticsearch is installed – Alex Kapustin Jun 18 '17 at 07:23
  • When my query structure was simply - data: { 'q': $('#message').val(), } it was working fine Alex. There was no issue with localhost. But since normal query was not solving my problem, I wanted to use match, hence the change. Hence, I am not sure localhost is an issue though I will check and come back. – Manganese Jun 18 '17 at 07:25
  • Doesn't work. Tried using both 127.0.0.1 (loopback) and 192.168.0.1 (site-local) on 9200. Same issue understandably. Plus, my elasticsearch is running locally for now anyway. – Manganese Jun 18 '17 at 07:40
  • And again, cURL is using localhost as well and working still. Guess must be some other issue. – Manganese Jun 18 '17 at 07:47

2 Answers2

3

From my experience the behavior of GET methods with a body is sometimes hard to predict. Actually, elastic search supports GET with body but I also had some strange results depending on the configuration of the servers, proxies and so on... The documentation even highlights the problems with javascript (search with GET).

Usually, using POST instead of GET helps to resolve these problems or at least to have a further debug option.

mugbi
  • 76
  • 3
  • Damn awesome is what it is! Thanks so much, works like a charm! And thanks for the doc reference as well. – Manganese Jun 18 '17 at 09:20
1

For those coming from Google, another way to solve this problem - or even if the POST solution doesn't work - is to use source parameter in the URL, as mentioned in docs[1].

$.ajax({
  type: "GET",
  url: "http://localhost:9200/firebase/_search?source_content_type=application/json&source=" + JSON.stringify(query),
  contentType: 'application/json',
  success: searchSuccess,
  dataType: 'json'
});

[1] https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#_request_body_in_query_string

Pedro Estevao
  • 700
  • 6
  • 34