0

I am trying to make a JSON document like this :

{
"query": {
  "bool":{
    "must":{
      "match": {
          "action": "HI"
      },
      "filter":{
        "range":{
          "epoch": {
              "gte" : "1454964688008"
          }
        }
      }
    }
  }
}

}

The condition is that match should always be before the filter JSONObject.

SO , seeing from this thread, I implemented something like this:

 public static String getQuery(Alert reqAlert) {


LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, Serializable>>>>> main = new LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, Serializable>>>>>();
        LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, Serializable>>>> query = new LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, Serializable>>>>();
        LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, Serializable>>> bool = new LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, Serializable>>>();
        LinkedHashMap<String, LinkedHashMap<String, Serializable>> must = new LinkedHashMap<String, LinkedHashMap<String, Serializable>>();
        LinkedHashMap<String, Serializable> match = new LinkedHashMap<String, Serializable>();
        LinkedHashMap<String, Serializable> filter = new LinkedHashMap<String, Serializable>();
        LinkedHashMap<String, LinkedHashMap<String, String>> range = new LinkedHashMap<String, LinkedHashMap<String, String>>();
        LinkedHashMap<String, String> epoch = new LinkedHashMap<String, String>();
        epoch.put("gte", "1454964688008");
        range.put("epoch", epoch);
        filter.put("range", range);
        match.put("action", reqAlert.getQueryString());
        must.put("match", match);
        must.put("filter", filter);
        bool.put("must", must);
        query.put("bool", bool);
        main.put("query", query);


        JSONObject mainObject = new JSONObject(main);

        return mainObject.toString();
        }

But it always print

{"query":{"bool":{"must":{"filter":{"range":{"epoch":{"gte":"1454964688008"}}}},"match":{"action":"HI"}}}}

What should I do?

Community
  • 1
  • 1
Priyansh Goel
  • 2,660
  • 1
  • 13
  • 37
  • 1
    The `JSONObject` constructor that you've used `JSONObject(Map, ?> map)` will change your maps to `HashMap`s so the order won't be preserver. – Titus May 20 '16 at 16:42
  • You can find answers here: http://stackoverflow.com/questions/4515676/keep-the-order-of-the-json-keys-during-json-conversion-to-csv. But as [top answer](http://stackoverflow.com/a/4515863/1970544) sugests, you shouldn't rely on fields' order. – Ernest Sadykov May 20 '16 at 16:45
  • Sorry, I didn't see that you linked the same question. The easiest way of making it work is described in the [second answer](http://stackoverflow.com/a/7981662/1970544): you should change the source of `JSONObject.java`. – Ernest Sadykov May 20 '16 at 16:49
  • @Titus : I updated the code, it still doesn't work. – Priyansh Goel May 20 '16 at 16:53
  • @ErnestSadykov : I don't want to change the code of JSONObject.java. I want to do it through my code only. – Priyansh Goel May 20 '16 at 16:53
  • @JorgeNieto : I am not trying to print json in pretty manner. I am trying to get the keys in a particular order. – Priyansh Goel May 20 '16 at 16:54
  • @PriyanshGoel The changes that you've made won't have any effect because, internally, `JSONObject` transfers all the values from your map to a `HashMap`. Other then changing the `JSONObject`'s source code I'm not sure if there is any other way to maintain the order. – Titus May 20 '16 at 16:56
  • @Titus : But as per http://stackoverflow.com/a/14496625/4183255 , I think it is possible. – Priyansh Goel May 20 '16 at 16:58
  • @PriyanshGoel The constructor in the source code I've looked at, doesn't do that, it loops through the map that you pass as a parameter and adds the entries to it's internal `HashMap`. I'm not sure which version of this json library you're using. It may be different, but given the results you're getting, I think your library is using the same constructor as the one I've mentioned. – Titus May 20 '16 at 17:13
  • @Titus: Yes you are right. Even I saw that. But given the fact that I have .class file of JSONObject, I can't edit it. – Priyansh Goel May 20 '16 at 17:14
  • You can download the library's source code, or use some other library, you can even manually create the `JSON` object using `String` concatenation because, it seems that only one of the values is not constant, the others, are always the same. For example `return "{.... :{\"action\":\"VALUE\"}}".replace("VALUE",reqAlert);` – Titus May 20 '16 at 17:26

1 Answers1

0

So that if somebody also has the same requirement, The best way to do it use a JSONObject from the following maven dependency.

       <dependency>
            <groupId>org.codehaus.jettison</groupId>
            <artifactId>jettison</artifactId>
            <version>1.3.5</version>
        </dependency>

Jettison uses LinkedHashMap internally.

Priyansh Goel
  • 2,660
  • 1
  • 13
  • 37