So I am using Firebase to store my data but for some reason the json file and web interface is different. Why is the JSON file in an array? How do I fix this? Thanks!
Web interface:
Json File:
{
"data" : [ {
"age" : "35",
"agratio" : "0.9",
"alb" : "3.3",
"alkphos" : "187",
"db" : "0.1",
"diagonsis" : "yes",
"gender" : "1",
"sgot" : "18",
"sgpt" : "16",
"tb" : "0.7",
"tp" : "6.8"
}, {
"age" : "35",
"agratio" : "0.9",
"alb" : "3.3",
"alkphos" : "187",
"db" : "0.1",
"diagonsis" : "no",
"gender" : "1",
"sgot" : "18",
"sgpt" : "16",
"tb" : "0.7",
"tp" : "6.8"
}, {
"age" : "35"
}, {
"age" : "20"
} ],
"users" : {
"234234adfsdsf" : {
"username" : "hey"
},
"BbZZCTIIcJdvCCU9og905kKVvo53" : {
"email" : "andyjiang55#yahoo.com",
"username" : "andyjiang"
}
}
}
The Firebase Realtime Database internally doesn't store array. It instead stores array-like structure as regular JavaScript objects/associative arrays, with the numeric sequential indexes as keys, like you see in the console.
The Firebase SDKs and REST API (which the export JSON feature uses under the hood) have logic built in to convert array-like JSON structures back to actual arrays when they see them. So that's why the exported JSON contains an array, while the console shows the actual structure that the database stores under the hood.
Also see:
the blog post Best Practices: Arrays in Firebase.
Related
I could not find proper solution to make use Newtonsoft JsonExtractor to parse Input file with new line delimiter.
From the Newtonsoft JsonExtractor I can read the first line successfully when exploded with "$.d.results[*]" but it's not moving to the next line,
As the data is >4MB for each row, can't extract as text. So parsing need to be performed using custom extractor to proceed.
Sample Input:
{"d":{"results":[{"data":{"Field_1":"1","Field_2":"2"},"Field_3":"3","Field_4":"4"}]}}
{"d":{"results":[{"data":{"Field_1":"11","Field_2":"21"},"Field_3":"31","Field_4":"41"}]}}
{"d":{"results":[{"data":{"Field_1":"12","Field_2":"22"},"Field_3":"32","Field_4":"42"}]}}
Expected Output:
Field_1|Field_2|Field_3|Field_4
1 |2 |3 |4
11 |21 |31 |41
12 |22 |32 |42
USQL Code:
CREATE ASSEMBLY IF NOT EXISTS [Microsoft.Analytics.Samples.Formats] FROM #"Microsoft.Analytics.Samples.Formats.dll";
CREATE ASSEMBLY IF NOT EXISTS [Newtonsoft.Json] FROM #"Newtonsoft.Json.dll";
REFERENCE ASSEMBLY [Microsoft.Analytics.Samples.Formats];
REFERENCE ASSEMBLY [Newtonsoft.Json];
USING Microsoft.Analytics.Samples.Formats.Json;
DECLARE #DATA_SOURCE string = "Input.data" ;
#SOURCE =
EXTRACT Field_1 string,
Field_2 string,
Field_3 string,
Field_4 string
FROM #DATA_SOURCE
USING new JsonExtractor("$.d.results[*]");
Considering your source input as below, i.e. more than one JSON document in a file.
{
"d": {
"results": [
{
"data": {
"Field_1": "1",
"Field_2": "2"
},
"Field_3": "3",
"Field_4": "4"
}
]
}
}
{
"d": {
"results": [
{
"data": {
"Field_1": "11",
"Field_2": "21"
},
"Field_3": "31",
"Field_4": "41"
}
]
}
}
{
"d": {
"results": [
{
"data": {
"Field_1": "12",
"Field_2": "22"
},
"Field_3": "32",
"Field_4": "42"
}
]
}
}
// if more than one JSON document in a file
The JSON assembly includes a MultiLevelJsonExtractor which allows us to extract data from multiple JSON paths at differing levels within a single pass. See the underlying code and inline documentation over at Github.
Use it by supplying multiple levels of Json Paths. They will be assigned to the schema by index.
The code snippet shows the MultiLevelJsonExtractor in action.
The first parameter (rowpath) specifies the base path to start from.
The second parameter (bypassWarning) is expecting a boolean value.
True = If path isn't found: don't error, return null. False = If path
isn't found: error.
The third parameter (jsonPaths) is a list of JSON paths starting at
the base path otherwise the extractor will recurse to the top of the
tree to locate it.
in your case....
#json =
EXTRACT
Field_1 string,
Field_2 string,
Field_3 string,
Field_4 string,
FROM
#DATA_SOURCE
USING new MultiLevelJsonExtractor("d.results[*]",
true,
"data.Field_1",
"data.Field_2",
"Field_3",
"Field_4",
);
I have this database:
{
"interpreters" : [ null, {
"InterpreterID" : "1",
"Name" : "Pedro",
"languages" : [ "portuguese", "russian", "english", "german" ],
"latitude" : 37.633,
"latitudeDelta" : 0.0143,
"longitude" : -122.345,
"longitudeDelta" : 0.0134
}, {
"InterpreterID" : "2",
"Name" : "Paulo",
"languages" : [ "english", "portuguese" ],
"latitude" : 37.554,
"latitudeDelta" : 0.0143,
"longitude" : -122.245,
"longitudeDelta" : 0.0134
} ]
}
And I'm trying to get only interpreters that match with the language I want. For example, get only interpreters
that speak russian.
I'm doing like this:
database()
.ref()
.child('interpreters')
.orderByChild('languages')
.equalTo('russian')
.on('value', snapshot => {
setInterpreters(snapshot.val())
console.log(snapshot.val())
});
But it returns 'null'.
If I look for orderByChild('Name').equalTo('Pedro') then return Pedros data.
Maybe it's because languages is an array but I'm not sure how to get data from it and couldn't find how to do it.
The forEach method simple didn’t work without any error. The code ran fine but I couldn’t display anything.
I'm following firebase documentation and seems that there is nothing different.
What should I do ?
Thank you in advance.
Firebase doesn't natively support arrays, well it does in form of objects. An array that you send as
["Portuguese", "Russian"]
is converted to
{0: "Portuguese", 1: "Russian"}
Hence your queries don't work as expected. Firebase doesn't support querying inner values of arrays
The workaround
Firebase recommends changing your data to:
{
"portugese": true,
"russian": true
}
and then query as
.orderByChild('languages/portuguese')
.equalTo(true)
I am working with:
Spring MVC
Spring MVC Testing
Assuming that a #Controller working with #ResponseBody returns a set of domain objects represented in JSON format and through print() method I can confirm the following:
Body = [ {
"id" : "88",
"nombre" : "Manuel",
"apellido" : "Jordan",
"fecha" : 1449370807750
}, {
"id" : "87",
"nombre" : "Leonardo",
"apellido" : "Jordan",
"fecha" : 1449370807750
}, {
...
}, {
...
}, {
...
} ]
Observe that content is an array.
Through Spring MVC Testing and with hamcrest I have the following:
resultActions.andExpect(jsonPath('$').exists())
.andExpect(jsonPath('$').isArray())
.andExpect(jsonPath('$',hasSize(5)))
…
Until here all work fine.
But assuming the #Controller returns just one element (One Domain Object) and again through the print() method I can see the following:
Body = {
"id" : "100",
"nombre" : "Jesús Você",
"apellido" : "Mão Nuñez",
"fecha" : 1449372342312
}
Observe it is not an array
I have currently the following:
resultActions.andExpect(jsonPath('$').exists())
//.andExpect(jsonPath('$').isArray()) <--- fails
.andExpect(jsonPath('$.*', hasSize(4) ))
How I can confirm the data returned is just one element?
It when is not an array.
I mean, I want have the same approach/behaviour about the following from XML
<persona>
<id>100</id>
<nombre>Jesús Você</nombre>
<apellido>"Mão Nuñez"</apellido>
<fecha>2015-12-05T22:00:07.756-05:00</fecha>
</persona>
Through
resultActions.andExpect(xpath("persona").exists())
.andExpect(xpath("persona").nodeCount(1))
Practically, what is the equivalent of xpath("persona").nodeCount(1) to jsonPath?
Thanks
Say you have exposed an API Product in Apigee. You would like to get a list of all the developers and their apps that have registered for the API Product.
There is a call to return those, documented here:
http://apigee.com/docs/api/get-list-keys-apps-developers-or-companies-api-product
But the IDs it returns appear to be useless. If you try developers, for instance:
https://api.enterprise.apigee.com/v1/organizations/YOUR-ORG/apiproducts/YOUR-PRODUCT?query=list&entity=developers
you get back a list of IDs. But to find which developer a given ID relates to is impossible, as the call to get a developer:
http://apigee.com/docs/api/get-developer
only accepts an email address.
How can I get a list of all the developers and their apps registered for a given API product?
The Apps a developer has is nested in each developer:
https://api.enterprise.apigee.com/v1/o/{your org}/developers
will return a list of developers like this:
["email#domain.com", "email2#domain2.com"]
Then you have to loop through each developer to get a list of their apps:
https://api.enterprise.apigee.com/v1/o/{your org}/developers/tesla#weathersample.com
Which gives you a bunch of meta data including apps:
{
"apps" : [ "weather" ],
"companies" : [ ],
"email" : "tesla#weathersample.com",
"developerId" : "Hk5mmLw9kKIM95qF",
"firstName" : "Nikolai",
"lastName" : "Tesla",
"userName" : "Nikolai",
"organizationName" : "jokeindex",
"status" : "active",
"attributes" : [ ],
"createdAt" : 1357858239543,
"createdBy" : "noreply_admin#apigee.com",
"lastModifiedAt" : 1357858239543,
"lastModifiedBy" : "noreply_admin#apigee.com"
}
Finally, if you look at each app you can see the products associated with that developer app:
https://api.enterprise.apigee.com/v1/o/{your org}/developers/tesla#weathersample.com/apps/weather
Gets you this detail:
{
"accessType" : "read",
"appFamily" : "default",
"appId" : "030fdcea-cf97-40b1-96df-12084aea513c",
"attributes" : [ {
"name" : "Developer",
"value" : "tesla#weathersample.com"
}, {
"name" : "DisplayName",
"value" : "Weather"
}, {
"name" : "Notes",
"value" : "not yet"
}, {
"name" : "lastModifier",
"value" : ""
} ],
"callbackUrl" : "http://example.com/callback",
"createdAt" : 1363578857830,
"createdBy" : "adminui#apigee.com",
"credentials" : [ {
"apiProducts" : [ {
"apiproduct" : "weather",
"status" : "approved"
} ],
"attributes" : [ ],
"consumerKey" : "{key}",
"consumerSecret" : "{key}",
"expiresAt" : -1,
"scopes" : [ ],
"status" : "approved"
} ],
"developerId" : "Hk5mmLw9kKIM95qF",
"lastModifiedAt" : 1386042817268,
"lastModifiedBy" : "michael.bissell#apigee.com",
"name" : "weather",
"scopes" : [ ],
"status" : "approved"
}
Take a look at the Org Snapshot Tool on git if you want to interrogate the entire org with one script:
https://github.com/apigee/api-platform-samples/tree/master/tools
This will interrogate every developer and every app and put it into a nice tree structure in your file system for future reference.
I have tables with different column and row count as JSON on client side, e.g.:
[
["", "Kia", "Nissan", "Toyota", "Honda"],
["2008", "-5", "11", "12", "13"],
["2009", "20", "-11", "14", "13"],
["2010", "30", "15", "-12", "readOnly"]
]
I want to send this table to server via ajax and ASP.NET Web Api. What is the best way to do this?
I always get null as value when i want to post as text and receive it as [FromBody]string value. I can't use a class because of different table sizes?
the answer was in the ajax code. I didn't had the right data parameter. Right is:
$.ajax({
url: '../webapi/Products',
type: 'POST',
dataType: "text",
data: "="+JSON.stringify( data ),
success: function (test) {
alert(test);
},
error: function (test) {
alert("Error");
}
then i can use e.g. JArray from JSON.NET to parse the value string.