I am writing a model factory, for which I use JSON to load up a MongoDB DBObject like this:
import com.mongodb.util.JSON;
DBObject dbObject = (DBObject) JSON.parse("{'name':'jack', 'age':30}");
Now, I am trying to break up my JSON files such that I can load up a DBObject with one JSON file, and if needed I can augment the DBObject with another JSON file.
Although it sounds weird, imagine having a set of different type of users. Like, BasicUser, AdvancedUser etc. I can have a JSON file to load up BasicUser, and put the other non-overlapping details of an AdvancedUser in another JSON file. I can make AdvancedUser extend BasicUser, and so I can just combine the contents of the two JSON files to create an AdvancedUser model.
How could I achieve something like this?
I believe putAll is what you want.
DBObject obj1 = (DBObject) JSON.parse("{'name':'jack', 'age':30}");
DBObject obj2 = (DBObject) JSON.parse("{'role':'admin'}");
obj1.putAll(obj2);
System.out.println(obj1.toString()); //{ "name" : "jack" , "age" : 30 , "role" : "admin"}
I decided to roll out my own function to do this by recursively traversing one DBObject and transferring the contents to another.
Related
I know the title is quite cliched, but it is not about storing JSON data in SQL Server.
I have a JSONArray with JSONObjects with keys that match the column names in SQL Server 2012. I want to save the data to the database into the proper columns.
I know the obvious way to do this is the iterate through the JSONArray and save the values with individual insert commands. I was wondering if there was another way to do this.
I don't want to use T-SQL. I want to handle this from Java only.
Here is an example data that matches the format of my JSONArray:
[
{
"FEATURE":"A",
"OPTION":"92384",
"ERROR_TYPE":"MISSING",
"DESCRIPTION":"Feature A is missing the option 92384",
"SERIAL_NUMBER":"249752-23894"
},
{
"FEATURE":"B",
"OPTION":"0288394",
"ERROR_TYPE":"MISSING",
"DESCRIPTION":"Feature B is missing the option 0288394",
"SERIAL_NUMBER":"Y2394-20392Q"
}
]
My SQLServer table looks like this:
What would be best way to achieve this without looping through each JSONArray?
As you have added java tag I would convert JSON to Java object and save it with Hibernate. Here are two useful links how to do that
Json to Java
Hibernate example
DECLARE #testJson NVARCHAR(4000)= N'[{"id":2,"name":"n2"},{"id":1,"name":"n1"}]'
INSERT
INTO
test_table SELECT
*
FROM
OPENJSON(#testJson) WITH (
id int N'$.id',
name VARCHAR(200) N'$.name'
)
Update
use java
jsonStr -> jsonObject and getKeys (some json libs )
String youJson = "{\"id\":0, \"name\":\"n0\"}";
JsonParser parser = new JsonParser();
JsonObject jsonObject = parser.parse(json).getAsJsonObject();
Set<String> keys = jsonObject.keySet();
Then use NamedParameterJdbcTemplate and MapSqlParameterSource (spring-jdbc) to create sql and set parameters dynamically .
PS. I hate ORM in java.
I have a simple dynamo table that consists of cookies and attributes:
customer
cookie
attribute_1
attribute_2
...
attribute_n
Right now, these attributes are variable and need to be updated upon receiving a partial JSON through and endpoint.
I made my mind into using the new JSON type field in DynamoDB (since that's our main datastore choice), and I intend to reshape the table into:
customer
cookie
attributes
Where attributes is just a JSON document.
Main issues:
I have no way of knowing which attributes are going to be added
I have no way ok knowing which items already exist (save from making an extra query)
I'd like to avoid a super complex code to do this
Main goal:
In an ideal world, there should be some way of having or not an item in dynamo and passing the primary key along with some JSON and then having the DB partially update the existing JSON.
So far I've seen this kind of code:
DynamoDB dynamo = new DynamoDB(new AmazonDynamoDBClient(...));
Table table = dynamo.getTable("people");
table.updateItem(
new UpdateItemSpec()
.withPrimaryKey("person_id", 123)
.withUpdateExpression("SET document.current_city = :city")
.withValueMap(new ValueMap().withString(":city", "Seattle")));
But I'd like to avoid making an extra query (to know if I need to create or update) and constructing all the update expressions.
Is there a way to do this?
Here is a full example just in case:
1) Receive the following JSON in the API:
{"name": "John"}
Expected dynamo attribute:
attributes={"name": "John"}
2) Receive the following JSON in the API:
{"age": 12}
Expected dynamo attribute:
attributes={"name": "John", "age": 12}
And so on. The primary key is constructed from the request cookie / customer.
My hopes for this existing comes from the fact that dynamo supports the smart updateItem (which I'm currently using) that allows to specify only some attributes to update or create an item.
Given some JSON value and a query in MongoDB format, I want to filter the same way that MongoDB does, the json entities I want without going to the MongoDB.
For example, I have:
JSON Value: [{qty: 10}, {qty: 30}, {qty: 50}]
Query in MongoDB format: { qty: { $gt: 20 } }
Result: [{qty: 50}]
I want that without going to Mongo database, for example calling some method that recives JSON Value and JSON Query String in Mongo format, inside some JAR.
Thanks!
I want that without going to Mongo database
Parse JSON using Jackson and create a Query Object and a Collection containing the target objects.
Use a collections framework such as Guava or GS-Collections and filter.
'Jackson' library offers JSON parsing & generation in Java. Once you've parsed, you can filter values/ data structure using Java code to your heart's content.
Java obviously has no direct implementation of Mongo query language.. you can implement Java code yourself as desired.
See:
http://jackson.codehaus.org/
I have a JSON string being sent from a client (browser ).I want to save it to my mongoDB database which already has some collections defined by the user.I was able to successfully save objects using Morphia.But How can I do the same if I already have the JSON string being returned from client I want to put in the "bands" collection.
Mongo mongo = new Mongo("localhost");
Datastore datastore = new Morphia().createDatastore(mongo,
"bandmanager");
Band band = new Band();
band.setName("Punjabi band");
band.getMembers().add("Lucky1");
band.getMembers().add("Lucky2");
band.getMembers().add("Lucky3");
band.getMembers().add("Lucky4");
band.getMembers().add("Lucky5");
band.getMembers().add("Lucky6");
band.setGenre("Punjabi");
datastore.save(band);
Did you annotate Band with #Entity("bands")? I'm not sure what you're asking... Are you asking how to convert that json string in to a Band object? If so, look in to jackson
If you already have a JSON object, you don't really need Morphia. You can simply do the following with the Java driver:
DBObject dbObject = (DBObject) JSON.parse(yourJsonString);
For a full blog post on this see http://www.mkyong.com/mongodb/java-mongodb-convert-json-data-to-dbobject/
PS: Do not forget to sanitize the JSON you get from the client!
I recently changed a POJO from having all its typed properties to something free in a typed JSONObject field called content.
The problem is that all old documents map to the old POJO version, so they are stored like this:
{"_id":"ObjectId(value)","field1":"value1","field2":"value2"}
Can I update all fields via a single mongo command so I can wrap all the content, except the id, so the result would be something like this:
{"_id":"ObjectId(value)","content":{"field1":"value1","field2":"value2"}}
?
Or should I program a simple program that does it one by one? (as in iterating all values sort of manually adding the new content level)
Unfortunately, there are no MongoDB commands that will allow you to restructure a document in this way. You'll need to write a program to fetch all of your documents one by one, update the structure, and then send the updated structure back to MongoDB.
Often the best way to do this is to write the modified documents to a new collection, and then drop the old collection when you're done.
I solved it creating a .js file to execute via mongo shell.
mongo myDb fixresults.js
The file is as follows:
for( var c = db.results.find(); c.hasNext(); ) {
var full = c.next();
var anon = db.results.findOne({"_id":full._id},{"_id":0});
var n = {"_id":full._id,"content":anon};
db.results.temp.insert(n);
}
This will insert the transformed value into the .temp collection, which you can rename later to replace the original.