How to get embedding elements in mongodb using Java - java

my json data is like bellow:
"scores": [
{
"type": "exam",
"score": 1
},
{
"type": "quiz",
"score": 2
},
{
"type": "homework",
"score": 3
},
{
"type": "homework",
"score": 4
}
]
I'm using below code to retrieve only score.
while(cursor.hasNext())
{
BasicDBObject acc=( BasicDBObject) cursor.next();
acc.get("scores");
for(int i=0;i<=acc.size();i++)
{
((BSONObject) acc.get(i)).containsField("score");
}
//System.out.println(acc);
}
I'm getting null point exception. What is wrong?

This is what you will have to do:
while(cursor.hasNext())
{
BasicDBObject acc=(BasicDBObject) cursor.next();
BasicDBList scores = (BasicDBList) acc.get("scores");
for(int i=0;i<scores.size();i++)
{
BasicDBObject score = (BasicDBObject) scores.get(i);
System.out.println(score.get("score"));
}
}
Few notes:
You need to loop the scores array (I assume it's array) and not the BasicDBObject itself. Hence you need to cast it to BasicDBList. Otherwise you will have to defend against Cast Exceptions
Java arrays elements are from 0...size()-1. So use < and not <= in your loop.

Related

Extract JSON key tags recursively - Java

I was curious if there was a way to extract all key tags (including children) within a JSON object within Java?
For example, say that I have this JSON object (the first one in a single line):
{"class":{"student":[{"firstname":"dinkar","grade":"A","nickname":["dinkar","dinkar jr"],"rollno":393,"marks":85,"lastname":"kad"},{"cars":{"model":[{"content":"Ford","spec":"RS"},"Toyota","Subaru"]},"firstname":"Vaneet","nickname":"vinni","friend":"Robert","rollno":493,"lastname":"Gupta"},{"firstname":"jasvir","nickname":"jazz","Driving":99,"rollno":593,"marks":90,"lastname":"singn"}]}}
And another view of the same JSON object:
{
"class": {
"student": [{
"firstname": "dinkar",
"grade": "A",
"nickname": ["dinkar", "dinkar jr"],
"rollno": 393,
"marks": 85,
"lastname": "kad"
}, {
"cars": {
"model": [{
"content": "Ford",
"spec": "RS"
}, "Toyota", "Subaru"]
},
"firstname": "Vaneet",
"nickname": "vinni",
"friend": "Robert",
"rollno": 493,
"lastname": "Gupta",
"firstname": "jasvir",
"nickname": "jazz",
"Driving": 99,
"rollno": 593,
"marks": 90,
"lastname": "singn"
}]
}
}
I want to obtain all key tags in this object but I do not know how many key tags there are. So what I've done is to recursively go through each element and put all unique JSON key tags into a JSON Array and print it off. This works for only the first layer, but what happens if there are multiple layers that I am unsure of? Please let me know if you have any suggestions, thanks.
List < String > JSON_tags = new ArrayList < String > ();
try {
//Obtaining root node
JSONArray root = JSONO.getJSONObject("class").getJSONArray("student");
for (int i = 0; i < root.length(); i++) {
Iterator keysI = ((JSONObject) root.get(i)).keys();
//root.getJSONObject(i).
while (keysI.hasNext()) {
String key = (String) keysI.next();
if (!JSON_tags.contains(key)) {
JSON_tags.add(key);
}
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//prints out a unique list of JSON tags
System.out.println(Arrays.toString(JSON_tags.toArray()));

MongoDB $regex query for "end with" particular char

I am not able to remove object from an array named Matrix for a Key match
BasicDBObject where = new BasicDBObject();
where.put("INSTITUTION_ID", instid);
where.put("RuleID", ruleid);
BasicDBObject obj1 = new BasicDBObject();
obj1.put("Matrix.Key",new BasicDBObject("$regex","/"+json.getString("Code")+"$/"));
collection.update(where,new BasicDBObject("$pull", obj1));
The code above is not removing object from array. The structure of the array can be found below
"Matrix" : [
{
"Key" : "6M",
"value" : "Queue"
},
{
"Key" : "6N",
"value" : "Queue"
},
{
"Key" : "6O",
"value" : "Queue"
}]
Command-line client
I suggest that before writing queries in Java notation, you first test them in the mongo console, with the regular JavaScript syntax. The following query works for me.
Data
db.matrix.insert(
{
INSTITUTION_ID: 1,
RuleID: 2,
Matrix: [
{
"Key": "6M",
"value": "Queue"
},
{
"Key": "6N",
"value": "Queue"
},
{
"Key": "6O",
"value": "Queue"
}
]
})
Query
db.matrix.update(
{
INSTITUTION_ID: 1,
RuleID: 2,
},
{
$pull:
{
Matrix:
{
Key:
{
$regex: /M$/
}
}
}
})
Data after the update
{
"INSTITUTION_ID" : 1.0000000000000000,
"RuleID" : 2.0000000000000000,
"Matrix" : [
{
"Key" : "6N",
"value" : "Queue"
},
{
"Key" : "6O",
"value" : "Queue"
}
]
}
Java
I am not sure how this update query should be represented in Java, but try this:
BasicDBObject where =
new BasicDBObject()
.put("INSTITUTION_ID", instid);
.put("RuleID", ruleid);
BasicDBObject update =
new BasicDBObject("$pull",
new BasicDBObject("Matrix",
new BasicDBObject("Key",
new BasicDBObject("$regex",
java.util.regex.Pattern.compile(json.getString("Code") + "$")))));
collection.update(where, update);

Extracting fields from JSON fields from mongodb

I want to extract all these places mentioned in "location" field and does not want the other fields in the below json.but can't be able to extract since it is nested..Can anyone help me?
DBCursor cursorTotal = coll.find(obje);
while (cursorTotal.hasNext()) {
DBObject curNext = cursorTotal.next();
System.out.println("data::"+curNext.get("list.myList.location");
}
My "curNext" gives output as::
{
"_id": {
"$oid": "51ebe983e4b0d529b4df2a0e"
},
"date": {
"$date": "2013-07-21T13:31:11.000Z"
},
"lTitle": "Three held for running CISF job racket",
"list": {
"myList": [
{
"location": "Germany"
},
{
"location": "Geneva"
},
{
"location": "Paris"
}
]
},
"hash": -1535814113,
"category": "news"
}
I want my output as
Germany,Geneva,Paris
I have been in a long wait here for an answer and finally I got what I was searching for...Just noting my answer so someone else can benefit from it
DBCursor cursorTotal = coll.find(obje);
while (cursorTotal.hasNext()) {
DBObject curNext = cursorTotal.next();
String res=curNext.toString();
JsonElement jelement = new JsonParser().parse(res);
JsonObject jobject = jelement.getAsJsonObject();
jobject = jobject.getAsJsonObject("list");
JsonArray jarray = jobject.getAsJsonArray("myList");
jobject = jarray.get(0).getAsJsonObject();
String result = jobject.get("location").getAsString();
System.out.println("all places::"+result);
}
For finding only locations you should used mongo aggregation, below query will fetch all lcoations array
db.collectionName.aggregate({
"$unwind": "$ner.nerList"
},
{
"$group": {
"_id": "$_id",
"location": {
"$push": "$ner.nerList.location"
}
}
},
{
"$project": {
"location": "$location",
"_id": 0
}
})
Unfortunately I don't know how to convert this in Java but, I find below links which helpfull to you for converting above query in java format
Mongo Java aggregation driver

Mongo group by query convert into java

How should I convert below mongo query in java, I used mongo java driver
db.demo.aggregate([
// Unwind the array
{ "$unwind": "$iInfo" },
// Sort the array elements within documents
{ "$sort": { "_id": -1, "iInfo.ifout": -1 } },
// Take only the "first" array element per document
{ "$group": {
"_id": "$_id",
"Iifout": { "$first": "$iInfo.ifout" },
"Iiferror": { "$first": "$iInfo.iferror" },
"Iifdes": { "$first": "$iInfo.ifdes" },
"Iifin": { "$first": "$iInfo.ifin" }
}},
// Group to push those results as an array
{ "$group": {
"_id": "$_id",
"iInfo": {
"$push": {
"ifout": "$Iifout",
"iferror": "$Iiferror",
"Iifdes": "$Iifdes",
"Iifin": "$Iifin"
}
}
}}
])
I write java code as below but it not work properly
BasicDBObject cmdBody = new BasicDBObject("aggregate",
collectionRealtime.toString());
pipeline.add(new BasicDBObject("$limit", 10));
pipeline.add(new BasicDBObject("$unwind", "$iInfo"));
pipeline.add(new BasicDBObject("$sort", new BasicDBObject(
"iInfo.ifout", -1)));
cmdBody.put("pipeline", pipeline);
when I run above java code it shows me all my nested output with sort but not shows in group and limit not work it display all documents.

Get sub-array from JSON

I parsing some data from a json file. Here is my JSON File.
[
{
"topic": "Example1",
"contact": [
{
"ref": [
1
],
"corresponding": true,
"name": "XYZ"
},
{
"ref": [
1
],
"name": "ZXY"
},
{
"ref": [
1
],
"name": "ABC"
},
{
"ref": [
1,
2
],
"name":"BCA"
}
] ,
"type": "Presentation"
},
{
"topic": "Example2",
"contact": [
{
"ref": [
1
],
"corresponding": true,
"name": "XYZ"
},
{
"ref": [
1
],
"name": "ZXY"
},
{
"ref": [
1
],
"name": "ABC"
},
{
"ref": [
1,
2
],
"name":"BCA"
}
] ,
"type": "Poster"
}
]
I can fetch and store data one by one. Like this one
JSONArray getContactsArray = new JSONArray(jsonObject.getString("contact"));
for(int a =0 ; a < getContactsArray.length(); a++)
{
JSONObject getJSonObj = (JSONObject)getContactsArray.get(a);
String Name = getJSonObj.getString("name");
}
1)Now, my question is there any way to get all name values for each array with single query.
2) Can I get all those values in an Array ?
Please correct me, if I am doing anything wrong. Thank you.
Iteration cannot be avoided here as org.json and other Json parsers as well provide random access to objects but not to their properties collectively (as a collection). So, you can't query something like "all name properties of all contact objects" unless you probably get a Json parser like Gson to unmarshall it that way.
But, that's too much to just avoid a for loop when you can definitely shorten the parse by making use of the appropriate API methods to avoid unnecessary object casts.
JSONArray contacts = jsonObject.getJSONArray("contact");
String[] contactNames = new String[contacts.length()];
for(int i = 0 ; i < contactNames.length; i++) {
contactNames[i] = contacts.getJSONObject(i).getString("name");
}
Better to use a json parser such as GSon or Jackson to marshall your json to a java object. Then you can write utitlity method in your java class to retrieve all the names in that object.
Try this:
Create JSONObject of your file and try to get array of all names and iterate it to get all values.
public static String[] getNames(JSONObject jo) {
int length = jo.length();
if (length == 0) {
return null;
}
Iterator i = jo.keys();
String[] names = new String[length];
int j = 0;
while (i.hasNext()) {
names[j] = (String) i.next();
j += 1;
}
return names;
}

Categories