且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

弹性搜索:cURL到Ajax请求

更新时间:2023-02-08 22:17:22

从我的经验来看,GET方法与身体的行为有时很难预测。实际上,弹性搜索支持GET与身体,但我也有一些奇怪的结果,取决于服务器,代理等的配置...文档甚至突出显示了JavaScript的问题(使用GET进行搜索)。



通常,使用POST而不是GET有助于解决这些问题,或至少有一个进一步的调试选项。


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:

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

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:

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:

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}

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.