I am new with JSON Query, trying to do a simple task but I could not find a solution online that I got working.
I have a json document like this:
[ {
"folder" : "User/Admin/UserA",
"User" : "Linda"
},
{
"folder" : "User/Service/UserB",
"User" : "John"
},
{
"folder" : "User/Admin/UserC",
"User" : "Peter"
} ]
I want to get all array elements under User/Admin/.
This Query gets me one result $..[?(#.folder==["User/Admin/UserA"])]
how can I make it more dynamic with a wildcard like $..[?(#.folder==["User/Admin/*"])]?
Tested with https://www.jsonquerytool.com/
Thank you for any help
you can use SelectToken with LINQ and Contains. For more complicated search you can use .StartsWith or .EndWith too.
var json = "...your json";
var jsonArr = JArray.Parse(json);
var users = jsonArr.ToArray()
.Where(m => m.SelectToken("folder").ToString().Contains("User/Admin/"))
.Select(u => u.SelectToken("User")).ToList();
result
Linda
Peter
or
var usersFolders = jsonArr.ToArray()
.Where(m => m.SelectToken("folder").ToString().Contains("User/Admin/")).ToList();
result
"folder": "User/Admin/UserA"
"User": "Linda"
"folder": "User/Admin/UserC"
"User": "Peter"
With ~Q (disclosure: I'm the main developer):
https://github.com/xcite-db/Unquery
{
"#return:[]?folder starts_with 'User/Admin'": ["."]
}
Result:
[
{
"folder": "User/Admin/UserA",
"User": "Linda"
},
{
"folder": "User/Admin/UserC",
"User": "Peter"
}
]
Related
I have this specific JSON file I'm not allowed to change, which looks like this :
{
"computers" : {
"John" : {
"version" : "1.42.0",
"environment" : "Default",
"platform" : "x64",
"admin" : "true"
},
"Peter" : {
"version" : "1.43.6",
"environment" : "Default",
"platform" : "x64",
"admin" : "true"
},
"Eric" : {
"version" : "1.43.6",
"environment" : "Default",
"platform" : "x64",
"admin" : "false"
}
}
I use the JSON.parse() method to parse the file and I put it into a MatTableDataSource.
Problem is, when I need to display it in my MatTable, I can't really access it the way I want.
I have a column where I want to display all version parameters, so for this I can't say : this.dataSource.computers.????.version
Do you guys see where I'm getting at ? Do you have any idea of what I can do differently in order to solve this ?
Looking forward to reading you.
The Angular mat-table requires the input data to be in an array. First, we use Object.keys() to extract the keys, which will contain the list of names. Then, we can use Object.values() to other values within each key in array format. This is followed by mapping the above array objects with the name property from the list of names.
const data = {
"computers": {
"John": {
"version": "1.42.0",
"environment": "Default",
"platform": "x64",
"admin": "true"
},
"Peter": {
"version": "1.43.6",
"environment": "Default",
"platform": "x64",
"admin": "true"
},
"Eric": {
"version": "1.43.6",
"environment": "Default",
"platform": "x64",
"admin": "false"
}
}
};
const nameList = Object.keys(data.computers);
const dataList = Object.values(data.computers).map((obj, index) => {
obj['name'] = nameList[index];
return obj;
});
console.log(dataList);
We are storing documents like this:
{
"FullName": "Jim",
"Children": [
{
"Name": "Sue",
"Hobbies": [
{
"Title": "Stamps",
"EnthusiasmLevel": 1
},
{
"Title": "Baseball",
"EnthusiasmLevel": 5
}
]
},
{
"Name": "Frank",
"Hobbies": [
{
"Title": "Dance",
"EnthusiasmLevel": 3
},
{
"Title": "Juggling",
"EnthusiasmLevel": 2
}
]
}
]
}
Usually when we are retrieving this "Jim" record, we'd want the full details on him and his children, but in certain circumstances we are going to want his name and just each child's name and the title of each of their hobbies.
Is there a straight-forward (or not) way of going about retrieving just parts of these documents while retaining (or rebuilding on the fly) their structure?
If I try something like:
SELECT p.FullName, [{"Name": child.Name}] AS Children
FROM People AS p
JOIN child in p.Children
I can construct an array, but I (obviously, per the join) get a record per child instead of one. If I instead remove the join and try to access these properties via the parent collection, I can't get at them.
What I want to get back is:
{
"FullName": "Jim",
"Children": [
{
"Name": "Sue",
"Hobbies": [
{"Title": "Stamps"},
{"Title": "Baseball"}
]
},
{
"Name": "Frank",
"Hobbies": [
{"Title": "Dance"},
{"Title": "Juggling"}
]
}
]
}
Even if I had to lose the structure, I'd still want to get back a single record representing "Jim" that contains his children's names and hobbies, but right now I'm just retrieving everything and doing the filtering on the client side, which is less than ideal.
Is what I'm after possible?
Based on your situation, I suggest you using Stored Procedure to process your data on the server side. I test sample code for you and it matches your requirements.
Sample Code:
function sample() {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT p.FullName, p.Children FROM People AS p',
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) {
var response = getContext().getResponse();
response.setBody('no docs found');
}
else {
var response = getContext().getResponse();
var returnResult = [];
for(var i = 0;i<feed.length;i++){
var peopleObj = feed[i];
ChildrenArray = [];
for(var j = 0;j<peopleObj.Children.length;j++){
console.log(j)
var childObj = peopleObj.Children[j];
HobbiesArray = [];
for(var k = 0; k < childObj.Hobbies.length;k++){
var hobbyObj = childObj.Hobbies[k];
map ={};
map["Title"] = hobbyObj.Title;
HobbiesArray.push(map);
}
childObj.Hobbies = HobbiesArray;
}
ChildrenArray.push(childObj);
}
returnResult.push(peopleObj);
getContext().getResponse().setBody(returnResult);
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
Output :
[
{
"FullName": "Jim",
"Children": [
{
"Name": "Sue",
"Hobbies": [
{
"Title": "Stamps"
},
{
"Title": "Baseball"
}
]
},
{
"Name": "Frank",
"Hobbies": [
{
"Title": "Dance"
},
{
"Title": "Juggling"
}
]
}
]
}
]
Any concern , please feel free to let me know.
I would suggest a simpler query-only solution. A la:
select jim.FullName,
ARRAY(
select child.Name,
ARRAY(
select hobby.Title from hobby in child.Hobbies
) as "Hobbies"
from jim join child in jim.Children
) as "Children"
from jim
While SP does have its uses, in this case I would consider this solution preferred over the SP because:
it is a lot simpler
it is more maintainable as it would keep your query logic in single place, query could be ran on any DB, without requiring any special permissions or preparation on server
It is better to keep application logic out of data layer. I.e. having the logic in app makes it possible to concurrently use multiple versions of this query.
haven't tested, but I'm pretty sure it is cheaper by RU.
I have a nested JSON returned from an API that I am hitting using a GET request, in POSTMAN chrome app. My JSON looks like this.
{
"resultset": {
"violations": {
"hpd": [
{
"0": {
"ViolationID": "110971",
"BuildingID": "775548",
"RegistrationID": "500590",
"Boro": "STATEN ISLAND",
"HouseNumber": "275",
"LowHouseNumber": "275",
"HighHouseNumber": "275",
"StreetName": "RICHMOND AVENUE",
"StreetCode": "44750",
"Zip": "10302",
"Apartment": "",
"Story": "All Stories ",
"Block": "1036",
"Lot": "1",
"Class": "A",
"InspectionDate": "1997-04-11",
"OriginalCertifyByDate": "1997-08-15",
"OriginalCorrectByDate": "1997-08-08",
"NewCertifyByDate": "",
"NewCorrectByDate": "",
"CertifiedDate": "",
"OrderNumber": "772",
"NOVID": "3370",
"NOVDescription": "§ 27-2098 ADM CODE FILE WITH THIS DEPARTMENT A REGISTRATION STATEMENT FOR BUILDING. ",
"NOVIssuedDate": "1997-04-22",
"CurrentStatus": "VIOLATION CLOSED",
"CurrentStatusDate": "2015-03-10"
},
"count": "1"
}
]
}
},
"count": "1",
"total_page": 1,
"current_page": 1,
"limit": [
"0",
"1000"
],
"status": "success",
"error_code": "",
"message": ""
}
I am trying to test whether my response body has "ViolationID":"110971".
I tried the below code in postman:
var jsonData =JSON.parse(responseBody);
tests["Getting Violation Id"] = jsonData.resultset.violations.hpd[0].ViolationID === 110971;
Two issues I noticed in the provided data. The following suggestions might help you:
Add missing closing braces at the end.
Add missing 0 in the index like this: resultset.violations.hpd[0].0.ViolationID
If the hpd array always contains only 1 member, the test might be pretty straightforward:
pm.test('Body contains ViolationID', () => {
const jsonBody = pm.response.json();
const violationId = jsonBody.resultset.violations.hpd[0]["0"].ViolationID;
pm.expect(parseInt(violationId)).to.eql(110971);
})
However, if hpd array might contain more than one member, it gets a bit trickier. I would suggest mapping only ViolationID keys from nested objects:
pm.test('Body contains ViolationID', () => {
const jsonBody = pm.response.json();
const violationIds = jsonBody.resultset.violations.hpd.map(hpd => hpd["0"].ViolationID);
pm.expect(violationIds).to.contain('110971');
})
Below is the document on which I am working:
{
"id": "idgwSRWDUJjQH",
"rev": "15-13d1d4545cd601560000000000000000",
"expiration": 0,
"flags": 0
}
{
"geminiType": "storegroup",
"_class": "web.model.StoreGroup",
"order": "10",
"childId": [
],
"name": "aaa",
"parent": "root",
"userGroupId": [
],
"type": "Folder",
"storeId": [
]
}
I am trying to sort based on name as below
function (doc, meta) {
if(doc.geminiType == "storegroup") {
emit(doc.name, [ meta.id,doc.name, doc.parent, doc.type]);
}
}
This I have created permanent view in couchbase console. I am fetching the document from my jave code using couchbase client as below:
View storeGrpView = cc.getView(RRConsts.STORE_GROUP_VIEW_DESIGN_DOC, RRConsts.STORE_GROUP_VIEW);
Query getAllstoreGrpQuery = new Query();
getAllstoreGrpQuery.setIncludeDocs(true);
getAllstoreGrpQuery.setStale(Stale.FALSE);
ViewResponse result = cc.query(storeGrpView, getAllstoreGrpQuery);
logger.info("getAllstoreGrpQuery resultset: " + result.toString());
for(ViewRow row : result) {
logger.info("store group :"+row.getDocument().toString());
}
}
Here I am getting the result in order of meta.id of the doc but i was expecting the result set to be in order of doc.name. Please let me know where I am doing wrong.
I got the solution to above issue. Actually if I used below two get method instead of row.getDocument() to fetch data, I am getting data in sorted order as expected.
row.getkey()
row.getvalue()
I have this two tables from the diagrams.For every question i can have multiple answer.
I want to get data by question id in json format like this:
var initialData = [
{question_id: "1", Description: "Danny", Status: "1", answers: [
{ answer_id: "1", description: "AAAAA" },
{ answer_id: "2", description: "Bbbbb" }]
}
];
I use this code
var question = db.Questions.FirstOrDefault((p) => p.questionID== id);
return this.Json(question , JsonRequestBehavior.AllowGet);
and i get this
var initialData = [
{question_id: "1", Description: "Danny", Status: "1", answers:null
}
];
Can you help my please with a solution.
Can you try this please.
var question = db.Questions.Include("Answer").FirstOrDefault((p) => p.questionID== id);
Have a look at the ado.Net blog