2

When I use MongoDB 2.x.x I used (BasicDBList) JSON.parse("[]") to parse the string data to Document array. But the latest MongoDB driver says this is deprecated and the BasicDbObject.parse("") only converts to BasicDBObject.

Here is some code samples I earlier used in 2.x.x Java driver

BasicDbList skuList = (BasicDBList) JSON.parse(skus);

So when I upgraded to 3.6.1, the compiler says this is deprecated. And suggested to use BasicDbObject.parse()

But this only accepts JSON objects structured Strings ...

{ "fruit": "apple"}

... not JSON array formatted Strings.

So, if i have a String like "[\"SKU000001\", \"SKU0000002\", \"SKU0000003\"]" how do I convert to BasicDBList?

glytching
  • 44,936
  • 9
  • 114
  • 120
Ajanthan
  • 198
  • 2
  • 10
  • `["SKU000001", "SKU0000002", "SKU0000003"]` -> this is a JSON array and must be converted to an ArrayList/DBList. How can each element be treated as document? – Rahul Raj Apr 13 '18 at 09:08
  • @RahulRaj Sorry, That was my English issue. I corrected them. My question is actually how to convert string to BasicDbList in mongo java driver 3.6.1. – Ajanthan Apr 13 '18 at 09:24

1 Answers1

6

JSON.parse() is capable of handling a JSON array, it reads the first character and if it deems the JSON to be an array it handles it accordingly:

case '[':
    value = parseArray(name);
    break;

BasicDBObject.parse() expects a valid JSON document so it will throw an exception when given an orphaned JSON array i.e. a JSON array which is not contained in a JSON document.

BasicDBObject.parse() can handle this ...

{"a": ["SKU000001", "SKU0000002", "SKU0000003"]}

... but it cannot handle this:

["SKU000001", "SKU0000002", "SKU0000003"]

So, there is no direct replacement in the MongoDB v3.x driver for using JSON.parse() to parse a JSON array. Instead, your options are:

  1. Trick BasicDBObject.parse() by presenting the JSON array in a valid JSON document, for example:

    BasicDBObject basicDBObject = BasicDBObject.parse(String.format("{\"a\": %s}",
            "[\"SKU000001\", \"SKU0000002\", \"SKU0000003\"]"));
    
    BasicDBList parsed = (BasicDBList) basicDBObject.get("a");
    assertThat(parsed.size(), is(3));
    assertThat(parsed, containsInAnyOrder("SKU000001", "SKU0000002", "SKU0000003"));
    
  2. Use a JSON parsing library to read the JSON array and then use the deserialised result to create a BasicDBList, for example::

    List<String> values = new ObjectMapper().readValue("[\"SKU000001\", \"SKU0000002\", \"SKU0000003\"]",
            List.class);
    
    BasicDBList parsed = new BasicDBList();
    values.forEach(s -> parsed.add(s));
    assertThat(parsed.size(), is(3));
    assertThat(parsed, containsInAnyOrder("SKU000001", "SKU0000002", "SKU0000003"));
    
glytching
  • 44,936
  • 9
  • 114
  • 120
  • Thank you. Actually that's what i though as a work around or just use the JSON.parse() with @suppress annotation. Let's wait and see if anyone got any good workarounds. – Ajanthan Apr 15 '18 at 06:16
  • Seems for now Mongo don't have any solutions. So I'm sticking with my Implementation. In which I'm converting to object formatted string then convert to BasicDBObject then get the BasicDBList from there. – Ajanthan Jun 14 '18 at 04:06