Inserting and fetching the Large JSON document in Couchbase? - json

I am trying to insert the Large JSON document in the Couchbase. I have inserted the document like below.
Bucket bucket = cluster.openBucket("default");
String jsondoc = "{{
"exams": {
"exam1": {
"year": {
"math": {
"questions": [
{
"question_text": "first question",
"options": [
"option1",
"option2",
"option3",
"option4",
"option5"
],
"answer": 1,
"explaination": "explain the answer"
},
{
"question_text": "second question",
"options": [
"option1",
"option2",
"option3",
"option4",
"option5"
],
"answer": 1,
"explaination": "explain the answer"
},
{
"question_text": "third question",
"options": [
"option1",
"option2",
"option3",
"option4",
"option5"
],
"answer": 1,
"explaination": "explain the answer"
}
]
},
"english": {same structure as above}
},
"1961": {}
},
"exam2": {},
"exam3": {},
"exam4": {}
}
}}";
JSONObject jsonObj = new JSONObject();
jsonObj.put("examinfo", jsondoc);
bucket.upsert(JSONDocument.create("exam", jsonObj));
After Inserting the document like above, I want to retrieve individual nested nodes(ex: questions) while fetching.
I have the following queries:
1) Can I Insert the document by using traditional approach:
String query = "upsert into default(KEY, VALUE) values(jsondoc)";
statement.executeUpdateQuery(query);
or Should I need to insert the above nested nodes individually in each JSONObject to fetch the nested nodes properly?
2) How to use N1QLQueryResult to fetch the each json document as a row only to fetch required json information

Which version of Couchbase are you using? There is a sub-doc API in version 4.5 that is for operating on parts of a JSON document:
http://developer.couchbase.com/documentation/server/4.5-dp/sub-doc-api.html
For your second question, you may want to look into the UNNEST N1QL operator.

Related

jOOQ JSON formatting as array of objects

I have the following (simplified) jOOQ query:
val result = context.select(
jsonObject(
key("id").value(ITEM.ID),
key("title").value(ITEM.NAAM),
key("resources").value(
jsonArrayAgg(ITEM_INHOUD.RESOURCE_ID).absentOnNull()
)
)
).from(ITEM).fetch()
Now the output that I want is:
[
{
"id": "0da04cc5-f70c-4fb3-b5c7-dc645d342631",
"title": "Title1",
"resources": [
"8b0f6d5c-67fc-47ca-be77-d1735e7721ce",
"ea0316db-1cfd-46d7-8260-5c1a4e65a0cd"
]
},
{
"id": "0f7e67e6-5187-47e2-9f1d-dab08feba38b",
"title": "Title2"
}
]
result.formtJSON() gives the following output:
{
"fields": [
{
"name": "json_object",
"type": "JSON"
}
],
"records": [
[
{
"id": "0da04cc5-f70c-4fb3-b5c7-dc645d342631",
"title": "Title 1"
}
]
]
}
Disabling the headers with result.formatJSON(JSONFormat.DEFAULT_FOR_RECORDS) will get me:
[
[
{
"id": "0da04cc5-f70c-4fb3-b5c7-dc645d342631",
"title": "Title1",
"resources": [
"8b0f6d5c-67fc-47ca-be77-d1735e7721ce",
"ea0316db-1cfd-46d7-8260-5c1a4e65a0cd"
]
}
],
[
{
"id": "0f7e67e6-5187-47e2-9f1d-dab08feba38b",
"title": "Title2"
}
]
]
where I don't want the extra array.
Further customizing the JSONformatter with result.formatJSON(JSONFormat().header(false).recordFormat(JSONFormat.RecordFormat.OBJECT)) I get:
[
{
"json_object": {
"id": "0da04cc5-f70c-4fb3-b5c7-dc645d342631",
"title": "Title1",
"resources": [
"8b0f6d5c-67fc-47ca-be77-d1735e7721ce",
"ea0316db-1cfd-46d7-8260-5c1a4e65a0cd"
]
}
},
{
"json_object": {
"id": "0f7e67e6-5187-47e2-9f1d-dab08feba38b",
"title": "Title2"
}
}
]
where I don't want the object wrapped in json_object.
Is there a way to get the output I want?
Doing it with Result.formatJSON()
This is clearly a flaw in the jOOQ 3.14.0 implementation of Result.formatJSON(). In the special case where there is only one column, and that column is of type JSON or JSONB, the column name may not really matter, and thus its contents should be flattened into the object describing the row. I've created a feature request for this: https://github.com/jOOQ/jOOQ/issues/10953. It will be available in jOOQ 3.15.0 and 3.14.4. You will be able to do this:
result.formatJSON(JSONFormat().header(false).wrapSingleColumnRecords(false));
The RecordFormat is irrelevant here. This works the same way for RecordFormat.ARRAY and RecordFormat.OBJECT
Doing it directly with SQL
Of course, you can always work around this by moving all the logic into SQL. You probably simplified your query by omitting a JOIN and GROUP BY. I'm assuming this is equivalent to what you want:
JSON result = context.select(
jsonArrayAgg(jsonObject(
key("id").value(ITEM.ID),
key("title").value(ITEM.NAAM),
key("resources").value(
select(jsonArrayAgg(ITEM_INHOUD.RESOURCE_ID).absentOnNull())
.from(ITEM_INHOUD)
.where(ITEM_INHOUD.ITEM_ID.eq(ITEM.ID))
)
))
).from(ITEM).fetchSingle().value1()
Note that JSON_ARRAYAGG() aggregates empty sets into NULL, not into an empty []. If that's a problem, use COALESCE()

Get array of JSON keys in react native

I have a JSON data in the format
[{
"Heading1": [{
"questionID": "q1",
"questionTitle": "Question 1",
"question": "This is question1",
"status": 0,
"files": [],
"uploadType": "none"
}, {
"questionID": "q2",
"questionTitle": "Question 2",
"question": "This is question2",
"status": 0,
"files": [],
"uploadType": "none"
}]
}, {
"Heading2": [{
"questionID": "q3",
"questionTitle": "Question 11",
"question": "This is a question11",
"status": 0,
"files": [],
"uploadType": "none"
}]
}, {
"Heading3": [{
"questionID": "q4",
"questionTitle": "Question 1",
"question": "This is a question",
"status": 0,
"files": [],
"uploadType": "none"
}]
}]
I'm trying to get all the titles in a format like [{"Title":"Heading1"},{"Title":"Heading2"},{"Title":"Heading3"}]
How should I go about it?
First, if you really have JSON (e.g., your starting point is a string, such as from an ajax response), you parse it via JSON.parse to get an array of objects. Then you loop the array and get the only key from each of those top-level objects via Object.keys(x)[0] and map that to an array of objects in the form you want:
const json = '[{"Heading1":[{"questionID":"q1","questionTitle":"Question 1","question":"This is question1","status":0,"files":[],"uploadType":"none"},{"questionID":"q2","questionTitle":"Question 2","question":"This is question2","status":0,"files":[],"uploadType":"none"}]},{"Heading2":[{"questionID":"q3","questionTitle":"Question 11","question":"This is a question11","status":0,"files":[],"uploadType":"none"}]},{"Heading3":[{"questionID":"q4","questionTitle":"Question 1","question":"This is a question","status":0,"files":[],"uploadType":"none"}]}]';
const parsed = JSON.parse(json);
const result = parsed.map(entry => {
return {Title: Object.keys(entry)[0]};
});
console.log(result);
The map callback can be a concise arrow function, but I thought using the verbose form above would be clearer. The concise form would be:
const result = parsed.map(entry => ({Title: Object.keys(entry)[0]}));
Note that using Object.keys in this way is only reliable if the objects really have just one property, as in your question. If they have more than one property, the order the properties are listed in the array from Object.keys is not defined (even in ES2015+, where properties do have an order — Object.keys is not required to follow that order [although it does on every modern engine I've tested]).

How to get the the node object or array from JSON based on excel sheet data using groovy?

Lets say I have the following JSON :-
{
"book": [
{
"id": "01",
"language": "Java",
"edition": "third",
"author": "Herbert Schildt"
},
{
"id": "07",
"language": "C++",
"edition": "second",
"author": "E.Balagurusamy"
}
]
}
And, I am passing the value of author from excel sheet to check if that author is present or not. If that author is present inside JSON, then that that particular array node only and remove other from the JSON.
For Example:- I am passing "author" value as "Herbert Schildt" from excel sheet. Now this value is present inside JSON, So, I need this particular array node to be printed and rest all should be removed. Like this:-
{
"book": [
{
"id": "01",
"language": "Java",
"edition": "third",
"author": "Herbert Schildt"
}
]
}
Can it be done using groovy? I have tried with HashMap but couldn't get through.
It's quite easy using groovy:
def text = '''{
"book": [
{
"id": "01",
"language": "Java",
"edition": "third",
"author": "Herbert Schildt"
},
{
"id": "07",
"language": "C++",
"edition": "second",
"author": "E.Balagurusamy"
}
]
}
'''
def result = groovy.json.JsonOutput.toJson(
[book: new groovy.json.JsonSlurper().parseText(text).book.findAll{it.author == "Herbert Schildt"}]
)
println result
You may try this ways json search
var json = '{"book":[{"id":"01","language":"Java","edition":"third","author":"Herbert Schildt"},{"id":"07","language":"C++","edition":"second","author":"E.Balagurusamy"}]}';
var parsed = JSON.parse(json);
var result = {};
result.book = [];
var author = "Herbert Schildt";
parsed.book.map((i, j) => {
if(i.author == author) {
result.book.push(i);
}
});
console.log(result)

Json Slupper assert and extract

I'm using the next Json
{
"ID": 8,
"MenuItems": [
{
"ID": 38,
"Name": "Home",
"URL": "{\"PageLayout\":\"Home\",\"Icon\":\"home\"}",
"Culture": "en",
"Children": null
},
{
"ID": 534,
"Name": "GUIDE ",
"URL": "{''PageLayout'':''Page A'', ''Icon'':''A''}",
"MenuType": 1,
"PageID": 0,
"Culture": "en",
"Children": [
{
"ID": 6,
"Name": "Form A",
"URL": "[''Type'':''Form A'',''Icon'':''Form'',''ItemID'':\"358\"]",
"Culture": "he",
"RuleID": 0
},
{
"ID": 60,
"Name": "Drama",
"URL": "[''Type'':''Form B'',''Icon'':''Form'',''ItemID'':\"3759\"]",
"Culture": "en",
"RuleID": 0
}
]
}
]
}
i'm using Groovy script in soapUI and i need to:
Assert the exitance of node that has the name GUIDE
Extract a list of all Itemsid
You can parse the JSON content using JsonSlurper and then work with the results like so:
import groovy.json.JsonSlurper
// Assuming your JSON is stored in "jsonString"
def jsonContent = new JsonSlurper().parseText(jsonString)
// Assert node exists with name GUIDE
assert(jsonContent.MenuItems.Name.contains("GUIDE"))
// Get list of ItemIDs
def itemList = jsonContent.MenuItems.Children.URL.ItemID[0].toList()
// List the items
itemList.each {log.info it}
Note that the above will fail given your current example, because of a few issues. Firstly, Name contains "GUIDE " (trailing space) rather than "GUIDE" (so you will need to adapt accordingly). Secondly, it is invalid JSON; the URL nodes have various erroneous characters.
On a side note, if you first need to retrieve your JSON from the response associated with a previous TestStep (say one called "SendMessage") within the existing testCase, this can be done as follows:
def jsonString = context.testCase.getTestStepByName("SendMessage").testRequest.response.getContentAsString()

Search JSON for multiple values, not using a library

I'd like to be able to search the following JSON object for objects containing the key 'location' then get in return an array or json object with the 'name' of the person plus the value of location for that person.
Sample return:
var matchesFound = [{Tom Brady, New York}, {Donald Steven,Los Angeles}];
var fbData0 = {
"data": [
{
"id": "X999_Y999",
"location": "New York",
"from": {
"name": "Tom Brady", "id": "X12"
},
"message": "Looking forward to 2010!",
"actions": [
{
"name": "Comment",
"link": "http://www.facebook.com/X999/posts/Y999"
},
{
"name": "Like",
"link": "http://www.facebook.com/X999/posts/Y999"
}
],
"type": "status",
"created_time": "2010-08-02T21:27:44+0000",
"updated_time": "2010-08-02T21:27:44+0000"
},
{
"id": "X998_Y998",
"location": "Los Angeles",
"from": {
"name": "Donald Steven", "id": "X18"
},
"message": "Where's my contract?",
"actions": [
{
"name": "Comment",
"link": "http://www.facebook.com/X998/posts/Y998"
},
{
"name": "Like",
"link": "http://www.facebook.com/X998/posts/Y998"
}
],
"type": "status",
"created_time": "2010-08-02T21:27:44+0000",
"updated_time": "2010-08-02T21:27:44+0000"
}
]
};
#vsiege - you can use this javascript lib (http://www.defiantjs.com/) to search your JSON structure.
var fbData0 = {
...
},
res = JSON.search( fbData0, '//*[./location and ./from/name]' ),
str = '';
for (var i=0; i<res.length; i++) {
str += res[i].location +': '+ res[i].from.name +'<br/>';
}
document.getElementById('output').innerHTML = str;
Here is a working fiddle;
http://jsfiddle.net/hbi99/XhRLP/
DefiantJS extends the global object JSON with the method "search" and makes it possible to query JSON with XPath expressions (XPath is standardised query language). The method returns an array with the matches (empty array if none were found).
You can test XPath expressions by pasting your JSON here:
http://www.defiantjs.com/#xpath_evaluator